其实我是想用nasm打印dx寄存器的内容。因此,内容是一个 16 位的十六进制数字,例如 0x12AB。
因此我首先实现了一个能够打印字符串的函数:
print_string:
pusha
mov ah, 0xe
print_character:
mov al, [bx]
inc bx
or al, al
jz print_done
int 0x10
jmp print_character
print_done:
popa
ret
你可以这样使用这个函数:
mov bx, MSG
call print_string
MSG:
db 'Test',0
现在我想要一个函数,将十六进制转换为字符串,以便 print_string 能够打印它。我在想这样的事情:
print_hex:
pusha
mov bx, HEX_OUT
; HEX_OUT is a kind of template string
; now i want to get the hex of dx into this template in order to be able to print it
; However I'm not sure how to manage this
call print_string
popa
ret
HEX_OUT:
db '0x0000', 0
不幸的是,我不确定如何将十六进制从 dx 分别获取到 bx,即 HEX_OUT。有人可以帮助我或有人有想法吗?
我想在最后像这样使用它:
mov dx, 0x12AA
call print_hex
提前谢谢你!
更新:
如前所述,我可以像这样实现分离和打印:
print_hex:
pusha
mov bx, PREFIX
call print_string
next_character:
mov bx, dx
and bx, 0xf000
shr bx, 4
add bh, 0x30
cmp bh, 0x39
jg add_7
print_character_hex:
mov al, bh
mov ah, 0x0e
int 0x10
shl dx, 4
or dx, dx
jnz next_character
popa
ret
add_7
add bh, 0x7
jmp print_character_hex
PREFIX:
db '0x', 0
我尝试用我的函数和缓冲区打印它:
print_hex:
;Added this here
mov cx, HEX_OUT + 2
print_character_hex:
mov [cx], bh
虽然由于“无效的有效地址”,我无法组装它。我需要做什么才能做到这一点?
最佳答案
这调整了接受的答案以包括 Kyle G. 对 0 问题的修复。
; vim: :set ft=nasm:
[bits 16]
; subroutine to print a hex number.
;
; ```
; dx = the hexadecimal value to print
; ```
;
; Usage
;
; ```
; mov dx, 0x1fb6
; call print_hex
; ```
;
; used as an answer here: https://stackoverflow.com/a/27686875/7132678
;
print_hex:
; push all registers onto the stack
pusha
; use si to keep track of the current char in our template string
mov si, HEX_OUT + 2
; start a counter of how many nibbles we've processed, stop at 4
mov cx, 0
next_character:
; increment the counter for each nibble
inc cx
; isolate this nibble
mov bx, dx
and bx, 0xf000
shr bx, 4
; add 0x30 to get the ASCII digit value
add bh, 0x30
; If our hex digit was > 9, it'll be > 0x39, so add 7 to get
; ASCII letters
cmp bh, 0x39
jg add_7
add_character_hex:
; put the current nibble into our string template
mov [si], bh
; increment our template string's char position
inc si
; shift dx by 4 to start on the next nibble (to the right)
shl dx, 4
; exit if we've processed all 4 nibbles, else process the next
; nibble
cmp cx, 4
jnz next_character
jmp _done
_done:
; copy the current nibble's ASCII value to a char in our template
; string
mov bx, HEX_OUT
; print our template string
call print_string
; pop all arguments
popa
; return from subroutine
ret
add_7:
; add 7 to our current nibble's ASCII value, in order to get letters
add bh, 0x7
; add the current nibble's ASCII
jmp add_character_hex
; our global template string. We'll replace the zero digits here with the
; actual nibble values from the hex input.
HEX_OUT:
db '0x0000', 0
此外,值得注意的是,这是来自 https://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf 的练习。 ,第 3.5.1 节,问题 5,第 23 页。
https://stackoverflow.com/questions/27636985/