【问题标题】:ebx register doesn't work in NASM but ecx workebx 寄存器在 NASM 中不起作用,但 ecx 起作用
【发布时间】:2019-12-13 21:44:51
【问题描述】:
section .data:
msg: db "Hello !"
msglen: equ $-msg

section .text:
      global _start:

_start:
      mov ebx,msg
      mov ecx,msglen
      mov eax,4
      int 80h
      mov eax,1
      int 80h

上面的代码不起作用。 但是下面的代码运行良好。

section .data:
    msg: db "Hello !"
    msglen: equ $-msg

    section .text:
          global _start:

    _start:
          mov ecx,msg
          mov edx,msglen
          mov eax,4
          int 80h
          mov eax,1
          int 80h

我所做的只是将 ebx 更改为 ecx 并将 ecx 更改为 edx。 这里发生了什么?

【问题讨论】:

  • 您在使用非工作代码时会遇到哪些错误(如果有)?你如何建造?你如何运行(如果你可以构建)?你所说的“不起作用”是什么意思?请花点时间刷新how to ask good questions,以及this question checklist
  • 你不能随意使用寄存器。系统调用需要特定寄存器中的特定参数。请参阅system call table。对于 sys_write,ebx 必须包含文件描述符、ecx 缓冲区和 edx 长度。 PS:我怀疑你使用了masm,这更有可能是nasm
  • nasm -f elf mycode.asm --> ld -m elf_i386 -s -o mycode mycode.oi 没有出现错误,构建阶段似乎没问题,但是当我使用 ebx 寄存器时输出什么都没有
  • " 我没有收到错误,构建阶段似乎还可以" 汇编器和链接器不了解系统调用的语义。那是操作系统的事情。您需要遵循操作系统指定的调用约定。
  • @Jester 哦,谢谢。我不知道这些信息。有什么书可以推荐给像我这样的菜鸟吗?

标签: linux assembly x86 nasm system-calls


【解决方案1】:

您的第二个代码有效,因为 write(0, "string", len) 恰好有效。 FD 0 是标准输入,但在终端程序中通常运行所有 3 个标准 FD,它们引用在 TTY 上以读/写方式打开的相同文件描述。

所以你可以写入标准输入,除非你把它重定向到一个文件。

内核在你的_start入口点进入用户空间之前将所有的regs归零,所以如果你不设置它,EBX = 0。 write(2) 将文件描述符作为其第一个参数。

使用strace ./a.out 查看您的系统调用。


您的第一个代码不起作用,因为write("string", len, 0) 将指针作为文件描述符编号传递,因此sys_write 将返回-EBADF(或-EFAULT,如果它首先检查len 是否是有效指针) .唯一有效的 fd 将是 0、1 或 2,除非您使用像 ./a.out 12345>&1 这样的重定向来打开 fd 12345 作为 1 的副本。再次使用strace

并阅读有关系统调用调用约定的文档。 What are the calling conventions for UNIX & Linux system calls on i386 and x86-64 有链接。

有关更多文档/手册和指南的链接,另请参阅 https://stackoverflow.com/tags/x86/info

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-31
    • 2012-05-21
    • 1970-01-01
    • 1970-01-01
    • 2013-08-25
    • 1970-01-01
    • 2013-01-31
    • 1970-01-01
    相关资源
    最近更新 更多