linux - 在 Linux 64 位中处理命令行

标签 linux assembly 64-bit

<分区>

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

.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

我的错误在哪里?

最佳答案

您正在将正确的地址加载到 %rcx

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

第二个系统调用 exit 工作正常,因为在这种情况下截断为 32 位不会造成任何伤害。


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

  • 使用系统调用,而不是int 0x80
  • 使用了不同的寄存器:参见here ;
  • 系统调用号也不同:参见here .

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

.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

关于linux - 在 Linux 64 位中处理命令行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3730064/

相关文章:

linux - Intel-64 和 ia32 原子操作获取-释放语义和 GCC 5+

assembly - Intel Core 2 Duo 预取

assembly - 从中断返回(RTI)和从子程序返回(RTS)之间的区别

c - IMAGE_REL_AMD64_ADDR64 64 位重定位

c# - x64 SQL Server 检测网络实例名称

c - 消息队列

python - 在进程列表中避免相关进程

COM 客户端/服务器跨 64/32 位进程

java - 无法使用 jsch 执行 sftp 子命令

assembly - 如何判断x86指令的长度?