Linux Assembly x86_64使用命令行参数创建文件

Sai*_*ire 1 linux assembly x86-64

我正在努力教自己装配.我找到了一个很好的网站 ; 但是,一切都是为x86编写的,我使用的是64位机器.

我知道问题是什么,但我不知道如何解决它.如果我用strace运行程序,那么结果如下:

execve("./file", ["./file", "hello"], [/* 94 vars */]) = 0
creat(NULL, 0)                          = -1 EINVAL (Invalid argument)
write(0, NULL, 0 <unfinished ...>
+++ exited with 234 +++
Run Code Online (Sandbox Code Playgroud)

所以,我知道当我调用时creat,文件名"hello"没有被传递,因此我没有文件描述符.

这是有问题的代码:

section .text
  global _start

_start:
  pop rbx ; argc
  pop rbx ; prog name
  pop rbx ; the file name

  mov eax,85 ; syscall number for creat()
  mov ecx,00644Q ; rw,r,r
  int 80h ; call the kernel 
Run Code Online (Sandbox Code Playgroud)

我知道我可以使用syscall命令; 但是,我想使用中断.

任何想法或建议都会有所帮助.另外,我正在使用nasm一个汇编程序.

Jes*_*ter 7

您试图使用32位机制.如果您有32位教程,您当然可以创建32位程序,这些程序将在兼容模式下按原样运行.但是,如果要编写64位代码,则需要使用64位约定和接口.这里,这意味着syscall具有适当寄存器的指令:

  global _start

_start:
  mov eax,85       ; syscall number for creat()
  mov rdi,[rsp+16] ; argv[1], the file name
  mov esi,00644Q   ; rw,r,r
  syscall          ; call the kernel 
  xor edi, edi     ; exit code 0
  mov eax, 60      ; syscall number for exit()
  syscall
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,另请参阅维基百科上的x86-64 sysv abi 或abi pdf.

  • 不确定值得一提的是`int 0x80`在这里不起作用的一个原因是`[rsp + 16]`通常包含一个指向堆栈的地址,当然还有64位基于堆栈的地址(Linux的方式)使用它们)不能在32位寄存器中表示,因此不能使用`int 0x80`约定.我完全同意他们应该使用`syscall`,我很好奇为什么OP不想走那条路. (2认同)
  • 哦,这不是答案,而是在这个问题的评论中./sf/ask/2488221501/.有人无法让"int 0x80"工作,并发现它已经构建了没有IA32仿真的内核. (2认同)