Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Segmentation Fault in Assembly Language

I am learning AT&T x86 assembly language. I am trying to write an assembly program which takes an integer n, and then return the result (n/2+n/3+n/4). Here is what I have done:

.text
.global _start
_start:
    pushl $24
    call profit
    movl %eax, %ebx
    movl $1, %eax
    int $0x80

profit:
    popl %ebx
    popl %eax
    mov $0, %esi
    movl $4, %ebp
    div %ebp
    addl %eax, %esi
    movl %ecx, %eax
    movl $3, %ebp
    div %ebp
    addl %eax, %esi
    movl %ecx, %eax
    movl $2, %ebp
    div %ebp
    addl %eax, %esi
    movl %esi, %eax
    cmpl %ecx, %esi
    jg end
    pushl %ebx
    ret

end:
    mov %ecx, %eax
    ret

The problem is I am getting segmentation fault. Where is the problem?

like image 294
user1700688 Avatar asked Sep 26 '12 15:09

user1700688


2 Answers

I think the code fails here:

_start:
    pushl $24
    call profit
    movl %eax, %ebx
    movl $1, %eax
    int $0x80

profit:
    popl %ebx
    popl %eax

So, you push $24 (4 bytes) and then call profit, which pushes eip and jumps to profit. Then you pop the value of eip into ebx and the value $24 into eax.

Then, in the end, if jg end branches to end:, then the stack won't hold a valid return address and ret will fail. You probably need pushl %ebx there too.

    cmpl %ecx, %esi
    jg end
    pushl %ebx
    ret

end:
    mov %ecx, %eax
    ; `pushl %ebx` is needed here!
    ret
like image 92
nrz Avatar answered Oct 13 '22 14:10

nrz


You do not appear to be doing function calls correctly. You need to read and understand the x86 ABI (32-bit, 64-bit) particularly the "calling convention" sections.

Also, this is not your immediate problem, but: Don't write _start, write main as if this were a C program. When you start doing something more complicated, you will want the C library to be available, and that means you have to let it initialize itself. Relatedly, do not make your own system calls; call the wrappers in the C library. That insulates you from low-level changes in the kernel interface, ensures that errno is available, and so on.

like image 37
zwol Avatar answered Oct 13 '22 12:10

zwol