由于代码中 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
我正在编写一个代码来将两个 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