I am new to assembly programming and trying to interpret the following code where I've to print an array present in the .data section : Here is the code:
%macro print 2
mov rax,1
mov rdi,1
mov rsi,%1
mov rdx,%2
syscall
%endmacro
%macro exit 0
mov rax,60
mov rdi,0
syscall
%endmacro
section .data
msg db 10,"Array is : ",10
len equ $-msg
array dq 11234H, 0AB32H, -3326H, 056BH
newline db 10
section .bss
buff resb 16;
section .code
global _start
_start:
print msg,len
mov rsi,array
mov rcx,4
back:
mov rbx,[rsi]
push rsi
push rcx
call HextoASCII
print newline,1
pop rcx
pop rsi
add rsi,8
loop back
exit
HextoASCII:
mov rsi,buff
mov rcx,16
back1:
rol rbx,4
mov al,bl
and al,0fh
cmp al,9h
jbe add_30h
add al,7h
add_30h:
add al,30h
mov [rsi],al
inc rsi
loop back1
print buff,16
ret
I have a few questions to ask to clear my doubts :
What is the default value of the variable present in the .bss section ?
The size of msg is 10 bytes(max size of msg), but when I put more characters into it, then it still prints the entire msg even though the string size exceeds its maximum limit(10 bytes).
If the numbers given in the array have their last(highest significant digit) as non-zero, doesn't it mean that the number is negative ie.- Isn't 11234H present in the array a negative number because I assume that the highest significant bits are present as 1 (FFF11234H) in the memory. I think that for a number to be non-negative its highest digit must be zero(011234), so that the higher ordered bits are stored as 0 in memory and make the number positive. If I'm wrong here then another thing to ask is whether FFFFFFFFH is -1 or a large positive number.
I am getting confused by the instruction
inc rsi
It is said that rsi is incremented by 1. But what is 1 here,bit or byte or 8 byte(size of rsi).
Adding 30H or 37H converts the hexadecimal digit to 39H or 41H and these are hexadecimal representation of 9 and A in ASCII but I do not understand why printing 39H or 41H will yield the result 9 or A on my monitor and not 39H or 41H itself. Is it that whatever our result is, the assembler prints its ASCII equivalent on the monitor. Also, In what form is the input that we give through keyboard interpreted by assembler/machine and if it is ASCII then do I need to convert it back to HEX explicitly for later calculations ?
After adding 30H or 37H,the single digit number(0H-9H or AH-FH) gets converted into double digit ranging from 30H-39H and 41H - 46H and so when we move this to buff, won't it actually occupy double the size of array element into buff to store it after the conversion ? I assume that earlier the digit took 4 bits and now it takes 8 bit after the conversion(9h is 4 bit and 39h is 8 bit). Do correct me, if I'm wrong here. If I'm right then, Is that the reason why buff is taken as 16 bytes when each array element size is just 8 bytes(quadword).
I understand the logic of HextoASCII which takes the highest digit of the number and stores it in buff and this goes on and later buff is printed but won't the number be printed in reverse manner because the highest digit of array element be stored at the least significant location of buff and as rsi is incremented the next digit will be added at the higher position of buff and so if we print buff then the most significant number gets placed at the least significant location of buff.ie-12H is store as 21 in buff because 1 is stored first in buff and later 2 is stored. Is there any importance of little endian and big endian here to store the digits ? Do explain, if yes.
In the print macro, 2nd argument is always the size of the variable that is to be printed.Here, the size of buff is 16 bytes and hence the second argument is 16. But if I make the 2nd argument as 8 then why is half of the digits of every array element not being printed but still the entire 8 digits are getting printed. Also, present me a case where half of the digits of every element of array will be printed, In that case will the higher significant 4 digits be printed or the lower significant 4 digits be printed ? Also, why ?