我正在尝试使用面向x86 GNU / Linux体系结构的 NASM 打印单个字符或数字。
这是我正在使用的代码:
section .text global _start _start: ; Linux printing preparation mov eax,4 mov ebx,1 ; Print 'A' character mov ecx,'A' ; ecx should contain the value to print mov edx,1 ; edx should contain how many characters to print int 80h ; System exit mov eax,1 mov ebx,0 int 80h
但是,运行此代码不会打印任何内容。我究竟做错了什么?
ecx应该包含一个指向char缓冲区开始的指针。因此,您必须将缓冲区存储在内存中。您可以执行以下操作:
ecx
; Print 'A' character mov eax, 4 ; __NR_write from asm/unistd_32.h (32-bit int 0x80 ABI) mov ebx, 1 ; stdout fileno push 'A' mov ecx, esp ; esp now points to your char mov edx, 1 ; edx should contain how many characters to print int 80h ; sys_write(1, "A", 1) ; return value in EAX = 1 (byte written), or error (-errno) add esp, 4 ; restore esp if necessary
您可以mov byte [esp], 'A'或其他任何地址(如果可以的话)覆盖堆栈中的所有内容。
mov byte [esp], 'A'
或者,您可以使用一个字符数组来section .rodata代替即时存储。
section .rodata
制作一个write()系统调用与const void *bufARG是些小号(像'A')将使其返回-EFAULT,不打印任何东西。内核仍然必须检查指针,并且系统调用将返回错误,而不是在错误的指针上引发SIGSEGV。
write()
const void *buf
'A'
-EFAULT
使用strace ./my_program跟踪你的系统调用 实际上 做,包括返回值进行解码。
strace ./my_program