Mã máy x86-16 (DOS), 16 byte
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
Hàm trên nhận được giá trị boolean (0 == falsey, 1 == truey) trong thanh BL
ghi (byte thấp BX
) và in chuỗi "boolean dự phòng" sang đầu ra tiêu chuẩn.
Nó hoạt động bằng cách gọi một ngắt (0x21) để thực hiện cuộc gọi chức năng DOS (được chọn bằng cách đặt AH
thành 2) để in một ký tự (in DL
) sang đầu ra tiêu chuẩn.
Đầu tiên, ký tự ASCII '0' được tải vào DL
, bộ đếm ( CX
) được đặt thành 31 và nó lặp để in các byte "dự phòng". Sau đó, giá trị boolean đầu vào được thêm vào DL
(nếu BL
là falsey, thêm 0 sẽ DL
không thay đổi dưới dạng ASCII '0'; nếu BL
là trung thực, DL
sẽ được tăng thêm một đến ASCII '1') và byte cuối cùng được in.
Hàm không trả về giá trị.
Khá tốt cho một ngôn ngữ không thực sự làm chuỗi.
Chương trình đầy đủ, 21 byte
Nếu bạn muốn biến nó thành một chương trình đầy đủ, chỉ cần thêm 5 byte. Thay vì chuyển đầu vào trong một thanh ghi, điều này đọc đầu vào từ các đối số được truyền trên dòng lệnh khi gọi ứng dụng. Một đối số bằng 0 được hiểu là falsey, cũng như thiếu hoàn toàn các đối số; một đối số lớn hơn 0 được hiểu là sự thật.
Đơn giản chỉ cần lắp ráp mã sau đây như một chương trình COM, và sau đó thực thi nó trên dòng lệnh.
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
Đầu ra mẫu:
C:\>bool.com
00000000000000000000000000000000
C:\>bool.com 0
00000000000000000000000000000000
C:\>bool.com 1
00000000000000000000000000000001
C:\>bool.com 2
00000000000000000000000000000001
C:\>bool.com 7
00000000000000000000000000000001
Làm thế nào nó hoạt động? Vâng, về cơ bản là điều tương tự, cho đến khi bạn nhận được CMP
hướng dẫn. Điều này so sánh đối số dòng lệnh với giá trị của thanh DL
ghi (mà bạn nhớ lại có chứa ASCII '0'). Trong chương trình COM, các byte mã được tải ở offset 0x100. Trước đó là tiền tố phân đoạn chương trình (PSP) , chứa thông tin về trạng thái của chương trình DOS. Cụ thể, ở offset 0x82, bạn tìm thấy đối số thứ nhất (thực ra là thứ hai, vì thứ nhất là khoảng trắng) được chỉ định trên dòng lệnh khi chương trình được gọi. Vì vậy, chúng tôi chỉ so sánh byte này với ASCII '0'.
So sánh đặt các cờ và sau đó là SALC
lệnh (một mã opcode không có giấy tờ trước Pentium, tương đương sbb al, al
, nhưng chỉ 1 byte thay vì 2) đặt AL
thành 0 nếu hai giá trị bằng nhau hoặc -1 nếu chúng khác nhau. Đó là sau đó rõ ràng rằng khi chúng ta trừ AL
từ DL
, kết quả này trong hoặc ASCII '0' hoặc '1', khi thích hợp.
(Lưu ý rằng, hơi mỉa mai, bạn sẽ phá vỡ nó nếu bạn vượt qua một đối số có số 0 đứng đầu trên dòng lệnh, vì nó chỉ nhìn vào ký tự đầu tiên. Vì vậy, 01
sẽ được coi là falsey. :-)