my teacher is doing a crash course in assembly with us, and I have no experience in it whatsoever. I am supposed to write a simple function that takes four variables and calculates (x+y)-(z+a) and then prints out the answer. I know it’s a simple problem, but after hours of research I am getting no where, any push in the right direction would be very helpful! I do need to use the stack, as I have more things to add to the program once I get past this point, and will have a lot of variables to store. I am compiling using nasm and gcc, in linux. (x86 64)
(side question, my ‘3’ isn’t showing up in register r10, but I am in linux so this should be the correct register… any ideas?)
Here is my code so far:
global main extern printf segment .data mulsub_str db "(%ld * %ld) - (%ld * %ld) = %ld",10,0 data dq 1, 2, 3, 4 segment .text main: call multiplyandsubtract pop r9 mov rdi, mulsub_str mov rsi, [data] mov rdx, [data+8] mov r10, [data+16] mov r8, [data+24] mov rax, 0 call printf ret multiplyandsubtract: ;;multiplies first function mov rax, [data] mov rdi, [data+8] mul rdi mov rbx, rdi push rbx ;;multiplies second function mov rax, [data+16] mov rsi, [data+24] mul rsi mov rbx, rsi push rbx ;;subtracts function 2 from function 1 pop rsi pop rdi sub rdi, rsi push rdi ret
Advertisement
Answer
push in the right direction
Nice pun!
Your problem is that you apparently don’t seem to know that ret
is using the stack for the return address. As such push rdi; ret
will just go to the address in rdi
and not return to your caller. Since that is unlikely to be a valid code address, you get a nice segfault.
To return values from functions just leave the result in a register, standard calling conventions normally use rax
. Here is a possible version:
global main extern printf segment .data mulsub_str db "(%ld * %ld) - (%ld * %ld) = %ld",10,0 data dq 1, 2, 3, 4 segment .text main: sub rsp, 8 call multiplyandsubtract mov r9, rax mov rdi, mulsub_str mov rsi, [data] mov rdx, [data+8] mov r10, [data+16] mov r8, [data+24] mov rax, 0 call printf add rsp, 8 ret multiplyandsubtract: ;;multiplies first function mov rax, [data] mov rdi, [data+8] mul rdi mov rbx, rdi push rbx ;;multiplies second function mov rax, [data+16] mov rsi, [data+24] mul rsi mov rbx, rsi push rbx ;;subtracts function 2 from function 1 pop rsi pop rdi sub rdi, rsi mov rax, rdi ret
PS: notice I have also fixed the stack alignment as per the ABI. printf
is known to be picky about that too.