I’m trying to make this program in assembly.
It should just convert a string to a decimal
int main (int argc, char **argv)
{
int result = 0;
char *c = argv[1];
while(*c != 0)
{
result *= 10;
result += (*c - 48);
c++;
}
return result;
}
but without getting argv from the stack… so I wrote a little code in asm that I think should do this but it does not work.
Can anyone point me to what I’m doing wrong?
I commented the code so you will know what I think is going on, please correct me with anything.
section .bss
buf resb 8 ; define an array of 8 uninitialised bytes
section .text
global _start
_start:
mov rax, 3 ; system call number (sys_read)
xor rbx, rbx ; file descriptor 0 (stdin)
mov rcx, buf ; buffer to store data
mov rdx, 8 ; Lenght of buffer
int 0x80
xor rax,rax ; rax = 0
mov rbx, buf ; rbx = &buf
xor rcx, rcx
StrToDec:
mov cl, [rbx] ; cl = *rbx
cmp rcx, 0 ; check for nul THIS IS WRONG
cmp rcx, 10 ; we have to check for NL ascii code
je end ; if rcx == 0 goto end
imul rax, 10 ; rax *= 10
sub rcx, 48 ; rcx -= 48 (48 is acii for '0')
add rax, rcx ; rax += rcx
inc rbx ; rbx++
jmp StrToDec
end:
mov rbx, rax ; rbx = rax
mov rax, 1 ; rax = 1
int 0x80
When i run this program and type 100 for example
and then type echo $? to the terminal it should print 100
Thanks.
FIXED:
I found out what was wrong with the program =D
First of all you need to check for value 10 so
is wrong because were looking for the new line ascii code not a null
is right, I don’t think it works if your getting the args from the stack, when getting args from stack you should check for 0.
Second: For numbers bigger than 255,
echo $? would give me wrong results, but that’s ok becauseecho $? can only show numbers up to 255, so even tho echo may show a wrong number the register rbx holds the right value.I debugged it and it works fine now.