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 上打开的读/写相同的文件描述。
因此,您可以写入 stdin,除非您将其重定向到文件。
内核在_start
入口点输入用户空间之前将所有注册清零,因此如果您不设置它,EBX = 0。write(2)
将文件描述符作为其第一个参数。
使用strace ./a.out
查看系统调用。
您的第一个代码不起作用,因为write("string", len, 0)
传递一个指针作为文件描述符编号,因此sys_write
将返回-EBADF
(如果它首先检查len
是否为有效指针,则返回-EFAULT
(。 唯一有效的 fds 将是 0、1 或 2,除非您使用像./a.out 12345>&1
这样的重定向将 fd12345
作为1
的副本打开。 再次,使用strace
.
并阅读有关系统调用调用约定的文档。 UNIX和Linux系统的调用约定是什么,i386和x86-64上的调用都有链接。
另请参阅 https://stackoverflow.com/tags/x86/info 以获取更多文档/手册和指南的链接。