I’ve written a simple program in assembly language, trying to run it on my 64bit Ubuntu OS. However, it failed for the “Segmentation fault (core dumped) error “.
Here is my code :
.section .data
values :
.int 10, 15, 20, 25, 30 ,35, 40, 45, 50, 55, 60
output :
.asciz "The value is %d\n"
.section .text
.globl main
main :
nop
movl $0, %edi
loop :
movl values( , %edi, 4), %eax
pushq %rax
pushq $output
call printf
addl $8, %esp
inc %edi
cmpl $11, %edi
jne loop
movl $0, %ebx
movl $1, %eax
int $0x80
There are multiple problems in your code.
From
64bit Ubuntuandpushq %raxI infer that you’re trying to make a 64-bit executable.If that’s the case, then…
Here:
you’re not properly balancing the stack after the function call. You still remember that this is 64-bit code? You need to add to
rsp, notesp. Also, if you push 2 8-byte parameters, you have to remove exactly 2 8-byte parameters, which means you have to add 16, not 8.But it’s even worse than that. In 64-bit mode parameters are passed differently. The first parameters are in the registers
rdi,rsi,rdx,rcx,r8andr9. So, that gives us:Here:
You just destroyed the value of
rdiby the call and by using this register for parameter passing. You need to manually pushrdiprior to the call and then pop it back. Or you could save it in a global variable. If you choose to push and pop, make sure than the stack pointerrspis always 16-byte-aligned before anycallinstruction.Here:
you are using the 32-bit system call interface. In 64-bit programs you have to use the 64-bit system call interface:
Now, I think this one may have problems too:
In general, you shouldn’t be using 32-bit registers and 32-bit instructions in address calculations in 64-bit code. I’d change it to:
If neither of the two works because the address of
valuesis more than 2GB away fromrip(fact: displacements are limited to 32-bit signed integers in memory operands in most instructions in 64-bit mode and most of them have no displacement-only memory operand encoding in 64-bit mode either, they userip-relative addressing there), you will need to manually add the 64-bit address ofvaluesand the index into the array multiplied by 4. Make sure you do a 64-bit addition without any truncations along the way.Must-reads:
System V Application Binary Interface AMD64 Architecture Processor Supplement Draft Version 0.99.6
Calling conventions for different C++ compilers and operating systems By Agner Fog