在 NASM 编程中将数据从变量移动到寄存器
Movement of data from variables to registers in NASM programming
以下是将数据段中初始化为"buff1"和"buff2"的两个数字相乘的代码。这些通过连续加法相乘,其中 buff1 在 rax 寄存器中被添加 buff2 次以给出结果,然后使用 tempbuff 变量通过 hex_ascii 过程显示。
%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 .bss
choice resb 2
tempbuff resb 16
section .data
menu db 10,"1. Successive addition"
db 10,"2. Add and Shift"
db 10,"Enter the choice : "
lenmenu equ $-menu
after db 10,"Product is : "
lenafter equ $-after
buff1 dw 0AH
buff2 dw 03H
newline db 0AH
section .code
global _start
_start:
print menu,lenmenu
accept choice,2
mov al,byte[choice]
case1:
cmp al,31H
jne case2
print after,lenafter
call succ_add
jmp _start
case2:
cmp al,32H
jne case3
call shift_add
jmp _start
case3:
exit
succ_add:
mov rax,0H
;mov rcx,0H ;Here is the problem
;mov cx,0H
mov bx,[buff1]
mov cx,[buff2]
back0:
add rax,rbx
loop back0
mov rbx,rax
call hex_ascii
ret
hex_ascii:
mov rcx,16
mov rax,0H
mov rsi,tempbuff
back1:
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 back1
print tempbuff,16
ret
shift_add:
exit;code for this section not written yet
ret
在上述 succ_add 过程中的代码中,如果我将 rcx 初始化为 0,那么我的代码可以正常工作(给出正确的结果);但是如果我将 cx 寄存器初始化为 0 然后将其分配为 [buff2] 那么它不会给我正确的结果。
由于循环是 运行 buff2 次(cx 次),那么即使我将 cx 初始化为 0 并分配给它 [buff2] ,问题是什么?
当我在我的代码中将 cx 初始化为 0 并将 rcx 初始化为 0 时有什么区别吗?
另外,另一个问题是,有什么方法可以将 2 字节大小的变量分配给 8 字节大小的寄存器吗?
enter image description here
在 64 位模式下,循环使用 rcx,而不是 cx。 mov cx,[buff2]只写cx——rcx的低16位
使用movzx ecx,单词[buff2]。这将初始化整个寄存器。 (低16位加载buff2的内容,其余寄存器为0。)所以不需要mov rcx, 0在它之前。
以下是将数据段中初始化为"buff1"和"buff2"的两个数字相乘的代码。这些通过连续加法相乘,其中 buff1 在 rax 寄存器中被添加 buff2 次以给出结果,然后使用 tempbuff 变量通过 hex_ascii 过程显示。
%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 .bss
choice resb 2
tempbuff resb 16
section .data
menu db 10,"1. Successive addition"
db 10,"2. Add and Shift"
db 10,"Enter the choice : "
lenmenu equ $-menu
after db 10,"Product is : "
lenafter equ $-after
buff1 dw 0AH
buff2 dw 03H
newline db 0AH
section .code
global _start
_start:
print menu,lenmenu
accept choice,2
mov al,byte[choice]
case1:
cmp al,31H
jne case2
print after,lenafter
call succ_add
jmp _start
case2:
cmp al,32H
jne case3
call shift_add
jmp _start
case3:
exit
succ_add:
mov rax,0H
;mov rcx,0H ;Here is the problem
;mov cx,0H
mov bx,[buff1]
mov cx,[buff2]
back0:
add rax,rbx
loop back0
mov rbx,rax
call hex_ascii
ret
hex_ascii:
mov rcx,16
mov rax,0H
mov rsi,tempbuff
back1:
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 back1
print tempbuff,16
ret
shift_add:
exit;code for this section not written yet
ret
在上述 succ_add 过程中的代码中,如果我将 rcx 初始化为 0,那么我的代码可以正常工作(给出正确的结果);但是如果我将 cx 寄存器初始化为 0 然后将其分配为 [buff2] 那么它不会给我正确的结果。 由于循环是 运行 buff2 次(cx 次),那么即使我将 cx 初始化为 0 并分配给它 [buff2] ,问题是什么? 当我在我的代码中将 cx 初始化为 0 并将 rcx 初始化为 0 时有什么区别吗? 另外,另一个问题是,有什么方法可以将 2 字节大小的变量分配给 8 字节大小的寄存器吗? enter image description here
在 64 位模式下,循环使用 rcx,而不是 cx。 mov cx,[buff2]只写cx——rcx的低16位
使用movzx ecx,单词[buff2]。这将初始化整个寄存器。 (低16位加载buff2的内容,其余寄存器为0。)所以不需要mov rcx, 0在它之前。