0

I am currently learning assembler language for the x64 architecture using the AT&T syntax, GNU Assembler and Linux as the kernel. My issue is when I try to use the open system call, the return error code the kernel returns is "EFAULT". I scoured the internet to find the issue with my code but to no avail can I seem to understand what I am doing wrong. Here is the section of code that is currently failing upon trying to open a file in the same directory as the binary:

`

.section .bss
    .lcomm fileBuffer, 50
    .lcomm fileHandle, 4

.section .data
filePath:
    .asciz "test.txt"
OPEN:
    .byte 5
READ:
    .byte 3
WRITE:
    .byte 4

.section .text
.globl _start

_start:
nop
movl %esp, %ebp

movb OPEN, %al #Put the value of the OPEN system call in the EAX register.
movq 16(%rbp), %rbx #Put the memory address of the string to the file in the EBX register.
movl $0102, %ecx #Put the file open options in the ECX register.
movl $0444, %edx #Put the file permissions in the EDX register.
int $0x80 #Call the software interrupt.

test %eax, %eax #Do a bitwise check to see if the value is zero.
js badfile

`

I am under the impression the issue is with the line

movq 16(%rbp), %rbx

since this is where I get the pointer to the file name. When inspecting memory contents starting at the memory location contained in the RBP register, I can see the address where the file name is located. This is the address that is returned by the previous instruction. Nonetheless, the kernel returns the EFAULT error code.

I am at a loss to why that is and to next steps that I can take to diagnose this issue. Any help concerning this issue would be greatly appreciated.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
200817189a
  • 21
  • 4
  • Surprised this gets as far as the `int $0x80` after you truncate RSP into EBP and dereference it. I'd have expected a segfault on `movq 16(%rbp), %rbx`. But anyway, `argv[1]` is a 64-bit pointer, which the 32-bit int 0x80 ABI will truncate, so yes -EFAULT is normal. [What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code?](https://stackoverflow.com/q/46087730) – Peter Cordes Nov 21 '22 at 14:12
  • Also, normally you'd define constants with `.equ SYS_OPEN, 5` so you can `mov $SYS_OPEN, %eax`. Or better, `#include ` to get CPP macro definitions of those constant (without any C prototypes or anything that wouldn't assemble.) Loading a byte into AL is weird because you're depending on the rest of RAX already being zero. That will be true at the start of a static executable, but nowhere else. – Peter Cordes Nov 21 '22 at 14:16

0 Answers0