ebx 寄存器在 NASM 中不工作,但 ecx 工作

ebx register doesn't work in NASM but ecx work

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。 这里发生了什么?

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

因此您可以写入标准输入,除非您将其重定向到文件。

在您的 _start 入口点输入 user-space 之前,内核会将所有寄存器清零,因此如果您不设置它,则 EBX = 0。 write(2) 将文件描述符作为第一个参数。

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


您的第一个代码不起作用,因为 write("string", len, 0) 将指针作为文件描述符编号传递,因此 sys_write 将 return -EBADF(或 -EFAULT 如果它首先检查 len 是否是一个有效的指针)。唯一有效的 fds 将是 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://whosebug.com/tags/x86/info 以获取指向更多 docs/manuals 和指南的链接。