如何在 Linux x86 NASM 中打印字符?
- 2024-10-25 08:42:00
- admin 原创
- 79
问题描述:
我正在尝试使用NASM打印单个字符或数字,针对 x86 GNU/Linux 架构。
这是我正在使用的代码:
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
但是,运行此代码时什么也没有打印。我做错了什么?
解决方案 1:
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'
任何其他地址或任何其他地址来覆盖堆栈上的内容。
或者您可以使用字符数组来section .rodata
代替动态存储。
如果系统调用的参数是write()
`const void *buf某个小数字(例如
'A'),则系统调用将返回
-EFAULT`而不打印任何内容。内核无论如何都必须检查指针,并且系统调用会返回错误,而不是在坏指针上引发 SIGSEGV。
用于跟踪您实际strace ./my_program
进行的系统调用,包括解码返回值。
解决方案 2:
您正在执行的系统调用需要ecx
包含内存中的地址。这可以是任意文字地址(即在您的代码中"A"
转换为地址041h
)、堆栈上的地址或程序中标签定义的地址。
下面是在内存中定义一个字节并将其写入终端的标准输出流的示例:
section .rodata ; This section contains read-only data
buffer: db 'A' ; Define our single character in memory
section .text
global start
_start:
; Prints the letter 'A', then exits
mov eax, 4 ; sys_write()
mov ebx, 1 ; ... to STDOUT
mov ecx, buffer ; ... using the following memory address
mov edx, 1 ; ... and only print one character
int 80h ; SYSCALL
mov eax, 1 ; Return to system
mov ebx, 0 ; Exit zero, success
int 80h ; SYSCALL
相关推荐
热门文章
项目管理软件有哪些?
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件
热门标签
云禅道AD