0

i just started to learn intel att assembly and met the next problem: i got segfault when i tried to use access to stack. i did access indirectly to memory location, but when i tried to do so with stack i got segfalt. my system is :

Linux cat 4.19.36 #1-NixOS SMP Sat Apr 20 07:16:05 UTC 2019 x86_64 GNU/Linux

i use gas comiler:

  as -gfstab  -o a.o a.s
  ld -o a.out a.o

this is example of my tiny code:

.code64
.globl _start
.text

_start:  
  movl (%esp) , %eax

  xor %eax , %eax
  inc %eax
  int $0x80

the program compiled and linked but when i tried to start it i got:

as -gfstab  -o a.o a.s
ld -o a.out a.o
./a.out 
make: *** [makefile:4: new] Segmentation fault

i used gdb to solve the problem. indirect access to stack gave me the next result:

6   movl (%esp) , %eax
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
_start () at a.s:6
6   movl (%esp) , %eax

i took this example from internet and they said that this is the way to do things. what i am doing wrong? TNX

Ston17
  • 115
  • 1
  • 7
  • 4
    You created a 64 bit program but tried to use 32 bit addresses. Either make a 32 bit program or rewrite the code to use 64 bit addresses. – Jester May 21 '20 at 18:04
  • thank you! i rewrite it just with rax and rsp and it works now! tnx – Ston17 May 21 '20 at 18:42

1 Answers1

0

Resolved!

the matter is that when you are in x64 mode you MUST use %r.. registers for working with stack. thats all

so the actual code looks like that:

.code64
.globl _start
.text

_start :  

  push $5 
  push $3
  push $2
  call myproc 
  add $24 , %rsp

  xor %rax , %rax
  inc %rax
  int $0x80

myproc :

  mov  8 (%rsp) , %rbx
  mov 16 (%rsp) , %rax
  add %rax , %rbx
  mov 24 (%rsp) , %rax
  add %rax , %rbx
  ret

tnx Jester for your help

Ston17
  • 115
  • 1
  • 7
  • 1
    The standard calling convention for 64-bit code passes the first 6 integer args in registers, only using the stack for the 7th and later. But yes, you should use 64-bit addressing modes, and need to for pointers that don't fit in 32 bits. And this example's inefficient custom calling convention does demonstrate using the stack. – Peter Cordes May 22 '20 at 06:36
  • 1
    Also note that `mov $1, %eax` is 5 bytes long, smaller and more efficient than `xor %rax,%rax` (3 bytes [including wasted REX prefix](https://stackoverflow.com/questions/33666617/what-is-the-best-way-to-set-a-register-to-zero-in-x86-assembly-xor-mov-or-and)) plus `inc %rax` (3 bytes). More importantly, don't use `int $0x80` in 64-bit code: [What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code?](https://stackoverflow.com/q/46087730) – Peter Cordes May 22 '20 at 15:47