由于代码中 al 和 ax 上的 shl 导致错误输出 NASM 64 位编程

Wrong output due to shl on al and ax in the code NASM 64 bit programming

我正在编写一个代码来将两个 8 位十六进制数相乘并应用移位和加法。我在名为 "a" 和 "b" 的变量中获取了两个字节类型的输入,并将它们存储在 al 和 bl.

乘法时,al左移,bl右移。 稍后,在循环中,我将 ax(a) 添加到 dx 寄存器(初始化为 0)。 但是,问题是当 shl ax,1 被替换为 shl al,1 那么我没有得到所需的输出。即 - a=12 和 b=10 然后只打印 20 而不是 120.

解释一下,为什么我不能写 shl al,1.

这是代码

%macro print 2
    mov rax,1
    mov rdi,1
    mov rsi,%1
    mov rdx,%2
    syscall
%endmacro

%macro accept 2
    mov rax,0
    mov rdi,0
    mov rsi,%1
    mov rdx,%2
    syscall
%endmacro

%macro exit 0
    mov rax,60
    mov rdi,0
    syscall
%endmacro

section .data
    a db 12H
    b db 10H
    msg db 10,"Result : ",10
    len equ $-msg
;------------------------
section .bss
    tempbuff resb 16    ;temporary buffer for displaying the ascii

;------------------------

section .text
global _start
_start:
    mov rdx,0
    mov al,byte[a]  ;al is multiplicand
    mov bl,byte[b]  ;bl is multiplier
    mov rcx,8
    lp:
        shr bl,1    
        jnc haha
        add dx,ax
        haha:
            shl ax,1    ;shl al,1 doesn;t work
    loop lp
    mov rbx,0
    mov rbx,rdx
    call hex_ascii      ;converting the hex no into ascii

exit

hex_ascii:
    mov rsi,tempbuff
    mov rcx,16
    mov rax,0
    bah:
        rol rbx,4
        mov al,bl
        and al,0FH
        cmp al,09H
        jbe add30
        add al,07H
        add30:
            add al,30H
        mov [rsi],al
        inc rsi
    loop bah
    print tempbuff,16   
ret

如果你在 al 中有一个 8 位的值,你想将它左移然后添加到 dx,你需要将 ax 左移,否则你会丢失位离开被乘数。换句话说,您想继续将其左移,保留所有位,并在每次您在乘数中看到 1 时添加到中间结果。

shl al,1 根本不影响 ah。它只影响 ah。这就是为什么你需要 shl ax,1。由于 shl al,1 转变

举个例子。最初:

al = 01011001
ax = 0000000001011001
bl = 00010111
dx = 0000000000000000

右移bl得到1位,左移al。我们从 bl 移位中得到 1 位,因此将 ax 添加到 dx:

al = 10110010
ax = 0000000010110010
bl = 00001011
dx = 0000000010110010

右移bl得到1位,左移al。我们从 bl 移位中得到 1 位,因此将 ax 添加到 dx:

al = 01100100
ax = 0000000001100100  <-- wrong! result of shifting al
bl = 00000101
dx = 0000000100010110  <-- wrong because ax was wrong

呃哦,麻烦了。 ax 现在是错误的。我们丢失了 al.

左移的位

这就是我们想要的:

al = 01100100
ax = 0000000101100100  <-- This is what we want, result of shifting ax
bl = 00000101
dx = 0000001000010110  <-- This is what we want, from correct ax

如果您查看 documentation for shl,您会发现 al 的高位在 shl al,1 指令中移入了 CF(进位标志)。如果您希望使用 "rotate through carry":

,则可以将该位旋转到 ah
shl al,1
rcl ah,1

但是你可以使用一条指令得到你想要的结果:

shl ax,1