Search code examples
linuxassemblycrashattmov

AT&T assembly try to "movb" a character constant to register, core dump


I'm using ubuntu64 + gas I use AT&T assembly, I tried to assign al register with a 'e', and compile it into 32 bit program

$ cat c2.s

.code32 
.globl _start 
_start: 
movb 'e',%al   # Problem here!!!!
mov $1,%eax 
mov $0,%ebx 
int $0x80 

$ as -g c2.s -o c2.o && ld c2.o -o c2

$ c2

Segmentation fault(SIGSEGV)

I used gdb to debug c2, and found it crash at movb 'e',%al. So weird, how could a "movb" crash?

Then I switched my syntax to use intel same content:

$ cat b2.s

.intel_syntax noprefix 
.code32 
.section .text 
.global _start 
_start: 
    mov al,'e' 
    mov eax,1 
    mov ebx,0 
    int 0x80 

$ as -g b2.s -o b2.o && ld b2.o -o b2

$ b2

This time, no problem. But why, is my usage of AT&T assembly has something wrong?


Solution

  • Isn't that interesting. AS produces this object code for AT&T syntax

      400078:   a0 65 00 00 00 b8 01    movabs 0x1b800000065,%al
      40007f:   00 00 
      400081:   00 bb 00 00 00 00       add    %bh,0x0(%rbx)
      400087:   cd 80                   int    $0x80
    

    obviously, location 0x1b800000065 is not mapped, but Intel;

      400078:   b0 65                   mov    $0x65,%al
      40007a:   b8 01 00 00 00          mov    $0x1,%eax
      40007f:   bb 00 00 00 00          mov    $0x0,%ebx
      400084:   cd 80                   int    $0x80
    

    remove .code32 from AT&T and you get this.

      400078:   8a 04 25 65 00 00 00    mov    0x65,%al
      40007f:   b8 01 00 00 00          mov    $0x1,%eax
      400084:   bb 00 00 00 00          mov    $0x0,%ebx
      400089:   cd 80                   int    $0x80
    

    Notice how it wants to move the contents of memory location 0x64 into AL.

    movb   $'e',%al
    

    fixes that problem. In any event, developing 32 bit code on a 64 bit system will probably give you grief at some point in time, especially when you start dealing with stack.