Assembly 程序集:打印时无意中添加十六进制数
我想在一个可引导的程序集文件中分别打印两个十六进制数。然而,打印第二个数字似乎会将其添加到第一个数字。正如一些人指出的那样,问题可能出在打印的十六进制部分 这是我的密码:Assembly 程序集:打印时无意中添加十六进制数,assembly,x86,nasm,x86-16,bootloader,Assembly,X86,Nasm,X86 16,Bootloader,我想在一个可引导的程序集文件中分别打印两个十六进制数。然而,打印第二个数字似乎会将其添加到第一个数字。正如一些人指出的那样,问题可能出在打印的十六进制部分 这是我的密码: [org 0x7c00] mov dx, [number1] call print_hex mov bx, space call print_string mov dx, [number2] call print_hex jmp $ ; Hang once
[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
我期望输出:
0x0001 0x0003
0x0001 0x0002
编辑:更新了代码和问题陈述,希望使其更加完整和可验证。因为print\u hex例程在hex\u OUT数据上使用add byte[bx],al
,它必然取决于hex\u OUT的初始内容
每次使用时只需重置内容:
print_hex:
pusha
mov ax, "00"
mov [HEX_OUT+2], ax
mov [HEX_OUT+4], ax
...
HEX_OUT: db '0x0000',0
使用调试器检查传递给
print\u hex
的dx
。另外,请尝试直接打印3
以验证print_hex
是否有效:)我确信print_hex.asm
与此问题有关。您是否有明确说明寄存器的所有(或大部分)内容都被保留或销毁的函数文档?我看到了include文件(以及jmp$
),不知道这是否在引导加载程序中?请将此作为一个示例。添加所有代码,包括两个包含文件中的代码,并向我们展示如何构建和运行程序。我必须同意,这似乎是例程print\u hex
的一些问题。因为我以前做过引导加载程序,所以我以前碰巧有同名的include文件。我起诉他们让一个引导加载程序(添加了一个引导签名和org 0x7c00)运行并工作。使用org0x100
将其构建为一个DOS COM程序,它也可以工作。如果你自己编码print_hex
,那么你可能有某种bug。啊,我明白了。非常感谢。我想提高投票率,但我还没有所需的+15声誉。@bjarke15接受后就行了。不取决于您当前的分数。