Skip to content
Advertisement

Why doesn’t this attempt at using sys_write do anything?

Here it is:

.SECTION .data
    msg: .string "AAAA"

.SECTION .text

.globl _start

_start:
    mov $1, %rax
    mov $1, %rdi
    mov msg, %rsi
    mov $4, %rdx
    syscall

Not only does this code not segfault, it also outputs nothing.
According to what I’ve read, a program should call sys_exit, or it would segfault, but this does not happen.

Advertisement

Answer

mov msg, %rsi

This instruction will interpret the data at “msg” as 64-bit value and load that value into the register rsi. The instruction does NOT load the address of “msg” into register rsi. This could be done by (note the $):

mov $msg, %rsi

According to what I’ve read, a program should call sys_exit, or it would segfault, but this does not happen.

You have to be aware why the segfault happens:

The CPU does not know where the “end” of your program is. The CPU can also not distinguish between instructions and data.

The bytes 0x8A, 0x07 for example may mean mov (%rdi),%al or they may represent the number 1930 – the CPU does not know.

When reaching the end of your program the CPU will try to read the bytes after your program and interpret them as instruction.

Now three scenarios are possible:

  • As RAM is managed in 4096 byte blocks on x86 systems. So depending on the length of your program up to 4095 bytes of “unused” RAM are following your program.

    The CPU will interpret the (random) bytes in the RAM as (assembler) instructions and execute these instructions.

    When reaching the end of the 4096 byte block a segfault is happening.

  • The 4095 bytes contain an instruction that causes a segfault (before the end of the block is reached).

  • The 4095 bytes represent instructions which cause the program to exit without any exception or an endless loop.

So maybe in your case the 3rd situation is the case.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement