【发布时间】:2016-10-20 07:15:42
【问题描述】:
我一直在学习如何编写操作系统的讲义,并且已经掌握了汇编语言,特别是 NASM。 (讲义在这里,感兴趣的:https://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf)
首要任务之一是编写一个程序,将 16 位十六进制数字的 ASCII 表示打印到屏幕上。
在下面的程序中,测试编号是'0x6bf1'。程序打印数字,但十六进制数字颠倒,即“01fb6”。我不知道为什么 - 有人能给我一个提示吗? (顺便说一句,这不是家庭作业)。
[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
【问题讨论】:
-
因为您正在处理从最低有效位到最高有效位的十六进制数字。
-
嗨迈克尔,我真的不知道怎么做,你介意解释一下吗?
-
@sav0h 试试这条线索:将
mov cl, 0更改为mov cl, 16或mov cl, 12并相应地调整循环。仔细检查退出条件! -
使用
shr ax, cland ax, 0x000f(然后在循环之前将 4 添加到 CL )。您似乎正在将您的数字从高位移到低位,然后处理低 4 位。因为您正在将处理数字从最不重要的十六进制转移到最重要的位置。这就像取十进制数 1234 并除以 1 并打印低位 (4) 然后除以 10 并打印低位 (3) 然后除以 100 并打印低位 (2) 然后除以 1000 和打印低位 (1)。结果将是 4321 -
哦...多么明显。不敢相信我没有看到。谢谢两位!