1

Apologies if this is trivial - i'm familiar with code but new to assembler and can't find many beginner-friendly resources online.

I want to get a simple print statement to run in a nasm 64-bit environment. I'm pulling in code that was originally working on 32-bit, but I can't figure out why it doesn't work here.

I've tried altering registers to use for example, rax instead of eax - from what I understand replacing the 'e' with an 'r' corresponds to the 64-bit register counterpart

;nasm 2.11.08
section .text
    global _start

_start:
    call func
    mov eax, 1
    mov ebx, 0
    int 0x80

func:
    mov ebp, esp ; ebp is the base pointer - holds the value of the top of the stack
    sub esp, 2 ; removing 16 bits (2 bytes) from our stack pointer. Means allocating 2 bytes on the stack
    mov [esp], byte 'H'
    mov [esp+1], byte 'i'
    mov eax, 4 ; sys write call
    mov ebx, 1
    mov ecx, esp
    mov edx, 2
    int 0x80
    mov esp, ebp ; puts stack back into state where it was
    ret

I compile this in a 64-bit environment - this website to be specific: https://rextester.com/l/nasm_online_compiler

However, I get the following error

Invalid memory reference (SIGSEGV

What I want see the output 'Hi' printed to the console. Any guidance is appreciated! Or simply resources that I can use to understand registers better

Cheers

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
Bejal
  • 91
  • 7
  • `mov esp, ebp ; puts stack back into state where it was` - how can you be certain that `ebp` hasn't been changed by the interrupt handler? For example, if the interrupt handler also saved `esp` to `ebp` it would trash the value your code had put there unless it saved `ebp` elsewhere first, etc, etc. I would think that to restore the stack pointer to its initial state you'd use `add esp, 2`, or just `ret 2` to have the return instruction handle the stack cleanup. YMMV. – Bob Jarvis - Слава Україні Jun 08 '19 at 19:46
  • 1
    The real rpoblem here is that rextester is assembling and running as 64-bit code. Your code uses 32-bit registers (including ESP and EBP) rather than RBP and RSP and on top of that to pass a 64-bit pointer to a system call requires changing from using the 32-bit interface (`int 0x80`) to the 64-bit `syscall` interface. – Michael Petch Jun 08 '19 at 20:24
  • @BobJarvis : The System V ABI defines what gets clobbered and what does on interrupt calls. In 32-bit code (using `int 0x80` EAX isn't preserved. In 64-bit code we use `syscall` instruction instead of `int 0x80`. The `syscall` instruction will clobber RCX, R11 and the Linux Int 0x80 interrupt handler will clobber EAX with a return value. Everything else is preserved. If calling `int 0x80` from 64-bit code R8-R11 may be clobbered (with 0) as well. – Michael Petch Jun 08 '19 at 20:26
  • thanks for pointing out a duplicate @michaelpetch, i'll check that out – Bejal Jun 08 '19 at 20:44
  • @Bejal Try to read both. Peter Cordes did a great job at writing the second one. – fuz Jun 08 '19 at 22:09
  • 1
    @fuz : For a beginner I think Martin's is more understandable and just so happens to be about doing output system call. – Michael Petch Jun 08 '19 at 22:18

0 Answers0