我已经制作了一个程序来在x64汇编语言(nasm)中添加数组的元素。但是当我显示总和时,它显示了一些其他不可读的结果。所以我询问了它,我发现我需要将总和转换为ASCII格式然后显示它。但我无法弄清楚这部分代码的作用。我已将该部分代码嵌入到我的程序中,现在它工作正常,但我无法理解这段代码实际上做了什么。这是我的计划:
global _start
section .data
arr1 dq 0000000000000001h,0000000000000002h,0000000000000003h,0000000000000004h,0000000000000005h
carry db 00
msg1 db 'Addition Is:',10
len1 equ $-msg1
msg2 db " "
len2 equ $-msg1
section .bss
addition resb 16
section .text
_start:
mov cl,4
mov rsi,arr1
mov rax,[rsi]
up: add rsi,8
add rax,[rsi]
jnc a1
inc byte[carry]
a1: dec cl
jnz up
call display ;ASCII conversion procedure display called
mov rax,1
mov rdi,1
mov rsi,msg1
mov rdx,len1
syscall
add byte[carry],30h
mov rax,1
mov rdi,1
mov rsi,carry
mov rdx,1
syscall
mov rax,1
mov rdi,1
mov rsi,addition
mov rdx,16
syscall
mov rax,60
mov rdi,0
syscall
display:mov rdi,addition ;How this procedure converts the addition into ASCII
mov cl,16
up1: rol rax,4
mov rbx,rax
and rax,0Fh
cmp rax,09h
ja dn1
add rax,30h
jmp dn
dn1: add rax,37h
dn: mov [rdi],rax
mov rax,rbx
inc rdi
dec cl
jnz up1
ret
答案 0 :(得分:1)
我已经用注释解释了代码的相关部分,这些注释解释了正在发生的事情。我将假设你知道base16算术和按位逻辑是如何工作的。如果没有,您将不得不在维基百科或其他地方查看。
mov cl,16 ; The loop counter (there are 16 digits)
up1: rol rax,4 ; Rotate the contents of rax 4 bits to the left. What were
; previously the 4 most significant bits will now be in
; the 4 least significant bits of rax. This is done because
; we want to print the most significant digit first.
mov rbx,rax ; Make a copy of the rotated version of rax.
and rax,0Fh ; Keep the 4 least significant bits of rax and set all other
; bits of rax to 0.
cmp rax,09h ; rax will now be in the range 0..15. Is it greater than 9?
ja dn1 ; ..if so, jump to dn1.
add rax,30h ; rax was in the range 0..9. The characters '0'..'9' are encoded as
; 30h..39h in ASCII, so add 30h to convert into a character.
jmp dn ; We're done with this case.
dn1: add rax,37h ; rax is in the range 10..15. The characters 'A'..'F' are encoded as
; 41h..46h in ASCII, so add 37h to convert into a character.
dn: mov [rdi],rax ; Store the character in the buffer pointed to by rdi.
mov rax,rbx ; Restore rax to the value it had right after the rol. So on the
; next iteration we'll be processing what were originally the
; second most significant 4 bits, and so on.
inc rdi ; Increment the buffer pointer.
dec cl ; Decrement the loop counter.
jnz up1 ; Repeat for all 16 digits.