Reputation: 238
I have made a program to add the elements of an array in x64 assembly languge(nasm). But when I display the sum it shows some other unreadable result. So I enquired about it and I found that I need to convert the sum into ASCII format and then display it. But I am unable to figure out what this part of code do. I have embedded that part of code into my program and now it is working fine, but I am unable to understand what this piece of code actually do. Here is my program:
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
Upvotes: 1
Views: 663
Reputation: 58427
I've annotated the relevant parts of the code with comments that explains what is going on. I'm going to assume that you know how base16 arithmetic and bitwise logic works. If not, you're going to have to look that up on wikipedia or somewhere else.
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.
Upvotes: 1