tags:

views:

96

answers:

2

Hi, I am trying to learn low-level development. By putting 0 in ebx and 1 in eax (for exit() syscall) and calling int 0x80, it should exit the program. I have a simple c program that runs fine, but when I paste this in, instead of exiting as expected, I get a segmantation fault. Why does this happen?

THANK YOU!

 __asm__ ("xor %ebx, %ebx;"
                 "mov %al, 1;"
                "int $80;"
);

edit: thanks for advice, still nothing but seg faults, though. here are modifications i've made:

  __asm__ ("xor %ebx, %ebx;"
           "xor %eax, %eax;"
                "mov $1, %eax;"
                "int $80;"
);

edit: after modifying this example from http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html

asm("movl $1,%%eax;         /* SYS_exit is 1 */
             xorl %%ebx,%%ebx;      /* Argument is in ebx, it is 0 */
             int  $0x80"            /* Enter kernel mode */
             );

This finally worked for me:

asm("   movl $1,%eax;
        xorl %ebx,%ebx;
        int  $0x80
"
        );

thanks for looking and offering advice.

+1  A: 

This looks like AT&T assembler syntax, so operations are in the order "operation source, target" as opposed to "operation target, source" in the more common Intel syntax.

Knowing this, mov %al, 1; tries to write the content of the al register to the memory position 1. Change it to mov 1, %al; and it should work IMO. Note that I have never used AT&T syntax, so I'm not sure whether I interpreted it correctly.

Edit: And Jeff M is right, the syscall number must be stored in the eax register, so make sure it is cleared.

AndiDog
+2  A: 

Are you sure the rest of eax is cleared? Try moving 1 into eax and not just al or at least clear it first.

__asm__ ("xor %ebx, %ebx;"
         "mov $1, %eax;"
         "int $0x80;"
);

edit: If AndiDog is right about AT&T syntax.

edit: It's been a while since I've used gas but 8016 is $0x80. $80 is 8010. This should fix the last of it.

Jeff M
tried clearing eax before moving the syscall (1), no change
healy
This works for me (x86-64/Linux, compiled with -m32) except that it should be "mov $1, %eax" instead of "mov 1, %eax" -- the latter tries to read memory at address 00000001, which, of course, segfaults. (And technically it should be "xorl" and "movl", but GAS seems to get it right regardless.)
Zack
@Zack: Ah yes, thanks for that. I was just making tweaks on healy's code as an example and forgot about the syntax. It's been a while... :)
Jeff M
@Zack: Forgot to mention that `MOV` in GAS is a synthetic instruction AFAIK and will be converted to the appropriate move instruction in the assembler when necessary. I know this applies on RISC architectures but wasn't aware it was necessary for x86 in particular.
Jeff M
I've spent a whole lot of time reading GCC assembly dumps but hardly any time writing assembly myself, so I didn't know that. Thanks for the tidbit!
Zack