DOS上的x86机器代码(.com文件)-71个字节
00000000 31 c9 68 20 24 89 e5 89 c8 bb 03 00 31 d2 f7 f3 |1.h $.......1...|
00000010 85 d2 74 1a 89 c8 b3 0a 31 d2 f7 f3 80 fa 03 74 |..t.....1......t|
00000020 0d 80 c2 30 86 d6 52 44 85 c0 75 ea eb 08 89 ec |...0..RD..u.....|
00000030 68 7a 74 68 62 7a 89 e2 b4 09 cd 21 89 ec 41 81 |hzthbz.....!..A.|
00000040 f9 f4 01 7e c2 59 c3 |...~.Y.|
使用空格作为分隔符将所需的输出打印到stdout;可以在DosBox中运行而不会出现问题。
评论程序集:
org 100h
start:
; 0 - 500 counter
xor cx,cx
; we'll use the stack as scratch space to build the strings to print
; first of all, push ' $' on the stack (in reverse order); this will be
; the end of each string we'll print
push 2420h
; save the stack pointer, to get back to this position after each print
mov bp,sp
mainloop:
; first try to divide by three
mov ax,cx
mov bx,3
xor dx,dx
div bx
test dx,dx
; no remainder => bzzt
jz bzzt
; otherwise, go into the decimal-print loop
mov ax,cx
divloop:
; bh is already at zero due to the mov bx,3 above
mov bl,10
xor dx,dx
; divide by 10
div bx
; remainder is 3 => bzzt
cmp dl,3
je bzzt
; convert number to digit
add dl,'0'
; trick: we move the digit to the upper byte of dx: this allows us to
; push the whole dx (you cannot do push dl) but to easily kill the
; undesidered byte by touching the stack pointer (it will be overwritten
; by the next stack operation/ignored by the print)
xchg dl,dh
push dx
inc sp
; check is there anything left to print, rinse & repeat
test ax,ax
jnz divloop
; skip straight to print
jmp print
bzzt:
; since we may be here from inside divloop, reset the stack pointer to
; where we left ' $'
mov sp,bp
; push 'bzzt'
push 747ah
push 7a62h
print:
; print what is on the stack
mov dx,sp
mov ah,9h
int 21h
; move us back to ' $'
mov sp,bp
; increment cx and repeat while we are <=500
inc cx
cmp cx,500
jle mainloop
end:
; fix back the stack pointer to the original value (=kill the first push)
pop cx
; quit
ret