Assembly 与AX和AL寄存器混淆

Assembly 与AX和AL寄存器混淆,assembly,x86,nasm,cpu-registers,Assembly,X86,Nasm,Cpu Registers,所以,我通过编写一个打印十六进制数的函数来计算汇编。 函数工作原理:在循环中,它获取数字的最后一位,将其转换为字符,并在HEX\u OUT字符串处替换字符(HEX\u OUT:DB“0x0000”,0,因此函数将重写每个字符以生成相应的数字),然后重复该操作,直到数字映射到HEX\u OUT字符串,然后打印出来 但我不明白寄存器有个问题。 问题是,当我将一些值放入ax寄存器(比如,6)中,然后将ax的值放入bx寄存器(mov[bx],ax),一天结束时,屏幕上会打印0x1,但如果我将指令更改为m

所以,我通过编写一个打印十六进制数的函数来计算汇编。 函数工作原理:在循环中,它获取数字的最后一位,将其转换为字符,并在
HEX\u OUT
字符串处替换字符(
HEX\u OUT:DB“0x0000”,0
,因此函数将重写每个字符以生成相应的数字),然后重复该操作,直到数字映射到
HEX\u OUT
字符串,然后打印出来

但我不明白寄存器有个问题。 问题是,当我将一些值放入
ax
寄存器(比如,
6
)中,然后将
ax
的值放入
bx
寄存器(
mov[bx],ax
),一天结束时,屏幕上会打印
0x1
,但如果我将指令更改为
mov[bx],al
,我得到了
0x1fb6
(假设要打印的数字是0x1fb6,这是正确的结果)

就我所知,由于我在
ax
中放置了
6
al
寄存器应该等于
ax
的值

请查看带有
[此处]
的注释行,这就是问题所在

; HEX_OUT ("0x0000") is stored in bx
; hexadecimal number to be printed (0x1fb6) is stored in dx

print_hex:
    pusha
    mov cx, 0                   ; cx = counter

loop1:
    cmp cx, 4                   ; if counter < 4
    jl print                    ; jump to print
    jmp end                     ; else jump to end

print:
    mov ax, dx                  ; ax = 0x1fb6
    and ax, 0x000f              ; ax = 6
    cmp ax, 9                   ; if ax > 9
    jg num_to_abc               ; make a letter out of char (because hexadecimal)
    jmp next                    ; jump to next

num_to_abc:
    add ax, 39
    jmp next

next:
    add ax, '0'                 ; make a char out of num
    mov bx, HEX_OUT + 5         ; bx now points to last char of string
    sub bx, cx                  ; bx = bx - counter
    mov [bx], al                ; [HERE] al is currently 54 (6 + '0'). But why al works properly, but ax doesn't?
    ror dx, 4                   ; put last digit at the beginning (before: 0x1fb6, after: 0x61fb)
    inc cx                      ; counter++
    jmp loop1                   ; jump back to loop

end:
    mov bx, HEX_OUT             ; some code
    call print_string
    popa
    ret

mov[bx],ax正在写入2个字节。因此,它覆盖了一个您可能不打算覆盖的额外字节。请注意,您可以通过从上半字节开始向左旋转来按打印顺序生成数字(这样您可以在缓冲区上向前而不是向后循环)。展示了如何。这使得使用更简单的索引更容易,循环中的指令更少。或者,由于一次打印使用1个字符,您可以将打印内容内联到数字循环中。此外,决不要在
jmp
上使用
jcc
,只需
jngnext
或进入
addal,'a'-10-'0'
。这是对内存的写入。
bx
的大小是不相关的。括号
[]
使其成为内存引用
mov bx,ax
将是寄存器之间的传输,
mov[bx],ax
是在地址
bx
处写入内存。内存中的额外字节将被覆盖。我还没有在你的代码中找到确切的原因,但是如果它与
al
一起工作,那肯定是问题所在。
print_string:       
pusha               
mov ah, 0x0e        
loop:               
    mov al, [bx]    
    cmp al, 0       
    je return       
    jmp put_char    
put_char:           
    int 0x10        
    inc bx          
    jmp loop        
return:             
    popa            
    ret