我一直在关注如何编写操作系统的讲义,并且已经掌握了汇编语言,特别是NASM。 (这里的讲义,感兴趣:https://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf)
首要任务之一是编写一个程序,在屏幕上打印一个16位十六进制数字的ASCII表示。
在下面的程序中,测试编号为“0x6bf1”。程序打印数字,但十六进制数字反转,即'01fb6'。我无法弄清楚为什么 - 有人能给我一个提示吗? (这不是家庭作业btw)。
[org 0x7c00] ; BIOS loads bootloader to address 0x7c00
mov dx, 0x6bf1
call print_hex
jmp $ ; Hang after printing result
print_hex:
mov cl, 0
mov bx, HEX_OUT
add bx, 2 ; To start writing after '0x'
loop:
cmp cl, 16
je finally
mov ax, dx
shr ax, cl
and ax, 0x000f
add ax, 0x30
cmp ax, 0x39
jg add_7
mov byte [bx], al
add bx, 1 ; Increment write address for the next round
add cl, 4 ; Increment bit shift for the next round
jmp loop
add_7: ; Handles letters (A-F)
add ax, 0x07
mov byte [bx], al
add bx, 1 ; Increment write address for the next round
add cl, 4 ; Increment bit shift for the next round
jmp loop
finally:
mov bx, HEX_OUT
call print_string
ret
print_string:
mov ah, 0x0e ; Set up for BIOS Teletype Routine
mov dx, bx
print_loop:
mov cl, [bx]
cmp cl, 0
je exit
mov al, [bx]
int 0x10
add bx, 1
jmp print_loop
exit:
ret
HEX_OUT: db '0x0000',0
; padding and magic BIOS number
times 510-($-$$) db 0
dw 0xaa55
答案 0 :(得分:3)
感谢Michael Petch和Margaret Bloom的评论,您已经知道代码出了什么问题。解决方案是有一个循环:
mov cl, 12
Loop:
mov ax, dx
shr ax, cl
...
sub cl, 4
jnb Loop
由于这不是作业,我们可以进一步学习编写更好的代码。主循环的主体是低效的,因为你重复了许多指令,这是不必要的。通过7:
跳过添加,看看代码有多小 mov cl, 12
Loop:
mov ax, dx
shr ax, cl
and al, 0x0F
add al, "0"
cmp al, "9"
jng isDigit
add al, 7 ; Handles letters (A-F)
isDigit:
mov byte [bx], al
inc bx ; Increment write address for the next round
sub cl, 4
jnb Loop
请注意,我使用AL
代替AX
。程序中这些点的AX
的高位字节没有相关内容。此外,使用AL
可以减少代码大小。使用inc bx
而不是add bx,1
也会减少代码大小。
BIOS Teletype功能以BH
为参数,因此在输出结果时最好不要使用BX
来迭代字符串。
为什么要加载角色2次(一次在CL
,一次在AL
)?
看看我如何将测试放在循环结束附近的字符串末尾?这节省了不必要的跳跃。在将来编写的程序中,这将成为一个重要的细节。
print_string:
mov si, bx
mov ah, 0x0E ; Set up for BIOS Teletype Routine - function number
mov bh, 0 ; Set up for BIOS Teletype Routine - display page
jmp TestEnd
print_loop:
int 0x10
inc si
TestEnd:
mov al, [si]
cmp al, 0
jne print_loop
ret