我想在可启动的程序集文件中分别打印两个十六进制数字。然而,打印第二个数字似乎将它添加到第一个数字。正如一些人所指出的那样,问题可能出在print_hex部分。
这是我的代码:
[org 0x7c00]
mov dx, [number1]
call print_hex
mov bx, space
call print_string
mov dx, [number2]
call print_hex
jmp $ ; Hang once we're done
print_hex:
pusha ; save the register values to the stack for later
mov cx,4 ; Start the counter: we want to print 4 characters
; 4 bits per char, so we're printing a total of 16 bits
char_loop:
dec cx ; Decrement the counter
mov ax,dx ; copy bx into ax so we can mask it for the last chars
shr dx,4 ; shift bx 4 bits to the right
and ax,0xf ; mask ah to get the last 4 bits
mov bx, HEX_OUT ; set bx to the memory address of our string
add bx, 2 ; skip the '0x'
add bx, cx ; add the current counter to the address
cmp ax,0xa ; Check to see if it's a letter or number
jl set_letter ; If it's a number, go straight to setting the value
add byte [bx],7 ; If it's a letter, add 7
; Why this magic number? ASCII letters start 17
; characters after decimal numbers. We need to cover that
; distance. If our value is a 'letter' it's already
; over 10, so we need to add 7 more.
jl set_letter
set_letter:
add byte [bx],al ; Add the value of the byte to the char at bx
cmp cx,0 ; check the counter, compare with 0
je print_hex_done ; if the counter is 0, finish
jmp char_loop ; otherwise, loop again
print_hex_done:
mov bx, HEX_OUT ; print the string pointed to by bx
call print_string
popa ; pop the initial register values back from the stack
ret ; return the function
print_string: ; Push registers onto the stack
pusha
string_loop:
mov al, [bx] ; Set al to the value at bx
cmp al, 0 ; Compare the value in al to 0 (check for null terminator)
jne print_char ; If it's not null, print the character at al
; Otherwise the string is done, and the function is ending
popa ; Pop all the registers back onto the stack
ret ; return execution to where we were
print_char:
mov ah, 0x0e ; Linefeed printing
int 0x10 ; Print character
add bx, 1 ; Shift bx to the next character
jmp string_loop ; go back to the beginning of our loop
; global variables
HEX_OUT: db '0x0000',0
number1: dw 1
number2: dw 2
space: db " ",0
; Padding and stuff
times 510-($-$$) db 0
dw 0xaa55
它给出了输出:
0x0001 0x0003
我期待输出:
0x0001 0x0002
编辑:更新了代码和问题陈述,希望使其更加完整和可验证。
答案 0 :(得分:3)
因为 print_hex 例程在 HEX_OUT 数据上使用add byte [bx],al
,所以它必然取决于 HEX_OUT 的初始内容。 / p>
每次使用时只需重置内容:
print_hex:
pusha
mov ax, "00"
mov [HEX_OUT+2], ax
mov [HEX_OUT+4], ax
...
HEX_OUT: db '0x0000',0