Linux 64位进程命令行

Ale*_*x F 5 linux 64-bit assembly

我在从Linux 64位汇编程序访问进程命令行时遇到问题.为了用最少的代码重现这个,我制作了这个32位程序,打印程序名称的前5个字符:

.section .text

.globl _start
_start:
 movl  %esp, %ebp

 movl $4, %eax        # write
 movl $1, %ebx        # stdout
 movl 4(%ebp), %ecx   # program name address (argv[0])
 movl $5, %edx        # hard-coded length
 int  $0x80

 movl $1, %eax
 movl $0, %ebx
 int  $0x80

这个程序正在运行.当我将其翻译为64位并在Linux 64中运行时,它不会打印任何内容:

.section .text

.globl _start
_start:
 movq  %rsp, %rbp

 movq $4, %rax
 movq $1, %rbx
 movq 8(%rbp), %rcx       # program name address ?
 movq $5, %rdx
 int  $0x80

 movq $1, %rax
 movq $0, %rbx
 int  $0x80

我的错误在哪里?

Mat*_*ery 10

您正在加载正确的地址%rcx.

int 0x80然后调用32位系统调用接口.将地址截断为32位,这使其不正确.(如果您使用调试器并在第一个之后设置断点int 0x80,您将看到它返回-14 in %eax,即-EFAULT.)

第二个系统调用,exit因为截断到32位不会做任何伤害在这种情况下,工程确定.


如果要将64位地址传递给系统调用,则必须使用64位系统调用接口:

  • 使用syscall,不int 0x80;
  • 使用不同的寄存器:见这里 ;
  • 系统呼叫号码也不同:见这里.

这是您的代码的工作版本:

.section .text

.globl _start
_start:
 movq  %rsp, %rbp

 movq $1, %rax
 movq $1, %rdi
 movq 8(%rbp), %rsi       # program name address ?
 movq $5, %rdx
 syscall

 movq $60, %rax
 movq $0, %rdi
 syscall
Run Code Online (Sandbox Code Playgroud)