x86-16 รหัสเครื่อง (DOS), 16 ไบต์
B4 02 mov ah, 2
B2 30 mov dl, '0'
B9 1F 00 mov cx, 31
PrintZeros:
CD 21 int 0x21
E2 FC loop PrintZeros
00 CA add dl, bl
CD 21 int 0x21
C3 ret
ฟังก์ชั่นด้านบนได้รับค่าบูลีน (0 == falsey, 1 == ความจริง) ในBL
รีจิสเตอร์ (ไบต์ต่ำBX
) และพิมพ์สตริง "บูลีนซ้ำซ้อน" ไปยังเอาต์พุตมาตรฐาน
มันทำงานได้โดยการเรียกใช้ขัดจังหวะ (0x21) เพื่อทำการเรียกฟังก์ชั่น DOS (เลือกโดยการตั้งค่าAH
เป็น 2) ที่พิมพ์อักขระเดียว (ในDL
) เพื่อออกมาตรฐาน
ขั้นแรกให้ใส่อักขระ ASCII '0' DL
ตัวนับ ( CX
) ตั้งค่าเป็น 31 และวนซ้ำเพื่อพิมพ์ไบต์ "ซ้ำซ้อน" จากนั้นค่าบูลีนอินพุตจะถูกเพิ่มลงในDL
(หากBL
เป็นเท็จการเพิ่ม 0 จะDL
ไม่เปลี่ยนแปลงเป็น ASCII '0' หากBL
เป็นความจริงDL
จะถูกเพิ่มขึ้นทีละหนึ่งเป็น ASCII '1') และพิมพ์ไบต์สุดท้าย
ฟังก์ชันไม่ส่งคืนค่า
ค่อนข้างดีสำหรับภาษาที่ไม่ได้ใช้สตริง
โปรแกรมเต็มรูปแบบ 21 ไบต์
หากคุณต้องการทำให้เป็นโปรแกรมเต็มรูปแบบต้องมีเพียง 5 ไบต์เท่านั้น แทนที่จะส่งผ่านอินพุตในรีจิสเตอร์สิ่งนี้อ่านอินพุตจากอาร์กิวเมนต์ที่ส่งผ่านบนบรรทัดรับคำสั่งเมื่อเรียกใช้แอ็พพลิเคชัน อาร์กิวเมนต์ 0 ถูกตีความว่าเป็นเท็จเช่นเดียวกับการขาดการโต้แย้งที่สมบูรณ์ อาร์กิวเมนต์ที่มากกว่า 0 ถูกตีความว่าเป็นความจริง
เพียงรวบรวมรหัสต่อไปนี้เป็นโปรแกรม COM แล้วดำเนินการบนบรรทัดคำสั่ง
B4 02 mov ah, 2
B2 30 mov dl, '0'
B9 1F 00 mov cx, 31
PrintZeros:
CD 21 int 0x21
E2 FC loop PrintZeros
3A 16 82 00 cmp dl, BYTE PTR [0x82] ; compare to 2nd arg, at offset 0x82 in PSP
D6 salc ; equivalent to sbb al, al
28 C2 sub dl, al
CD 21 int 0x21
C3 ret ; you can simply 'ret' to end a COM program
ตัวอย่างผลลัพธ์:
C:\>bool.com
00000000000000000000000000000000
C:\>bool.com 0
00000000000000000000000000000000
C:\>bool.com 1
00000000000000000000000000000001
C:\>bool.com 2
00000000000000000000000000000001
C:\>bool.com 7
00000000000000000000000000000001
มันทำงานยังไง? มันเหมือนกันจนกว่าคุณจะได้CMP
รับคำแนะนำ สิ่งนี้จะเปรียบเทียบอาร์กิวเมนต์บรรทัดคำสั่งกับค่าของการDL
ลงทะเบียน (ซึ่งคุณจำได้ว่ามี ASCII '0') ในโปรแกรม COM โหลดไบต์ของรหัสที่ออฟเซ็ต 0x100 ก่อนหน้านั้นคือส่วนนำหน้าของโปรแกรม (PSP)ซึ่งมีข้อมูลเกี่ยวกับสถานะของโปรแกรม DOS โดยเฉพาะอย่างยิ่งที่ออฟเซ็ต 0x82 คุณจะพบอาร์กิวเมนต์แรก (อันที่สองจริงเนื่องจากอาร์กิวเมนต์แรกคือช่องว่าง) ที่ระบุไว้ในบรรทัดคำสั่งเมื่อโปรแกรมถูกเรียกใช้ ดังนั้นเราแค่เปรียบเทียบไบต์นี้กับ ASCII '0'
การเปรียบเทียบตั้งค่าสถานะแล้วSALC
คำสั่ง (opcode ที่ไม่มีเอกสารก่อน Pentium เทียบเท่ากับsbb al, al
แต่เพียง 1 ไบต์แทน 2) ตั้งค่าAL
เป็น 0 ถ้าทั้งสองค่าเท่ากันหรือ -1 ถ้าพวกเขาแตกต่างกัน แล้วมันเป็นที่ชัดเจนว่าเมื่อเราลบAL
จากDL
ผลนี้ทั้งใน ASCII '0' หรือ '1' ตามความเหมาะสม
(โปรดสังเกตว่าค่อนข้างเป็นเรื่องประชดประชันคุณจะทำลายมันถ้าคุณผ่านการโต้แย้งด้วย 0 นำหน้าในบรรทัดคำสั่งเนื่องจากมันดูเฉพาะอักขระตัวแรกเท่านั้นดังนั้น01
จะถือว่าเป็น falsey :-)