尝试向预留字节传递字符串仅读取部分字符的技术求助
问题原因分析
核心问题是**mov指令无法直接将超过操作数长度的字符串立即数一次性写入内存**:
- 使用
mov byte [teste], "hello world"时,byte限定操作数长度为1字节,汇编器仅会提取字符串的第一个字符'h'写入teste指向的内存。 - 改为
qword后,32位x86汇编环境下mov指令无法直接处理64位立即数(32位模式下寄存器、内存操作数默认是32位),汇编器会自动截断字符串为32位(4字节),也就是前4个字符"hell",因此最终仅输出这4个字符。
解决方法
要将完整的"hello world"写入teste变量,有两种常用方案:
方案1:分块使用mov指令写入
把字符串拆分为多个匹配操作数长度的块,依次写入内存:
section .bss teste resb 1024 section .text global main main: ; 分块写入完整字符串 mov dword [teste], "hell" ; 写入前4字节: 'h','e','l','l' mov dword [teste+4], "o wo" ; 写入接下来4字节: 'o',' ','w','o' mov word [teste+8], "rl" ; 写入接下来2字节: 'r','l' mov byte [teste+10], 'd' ; 写入最后1字节: 'd' ; 系统调用输出,注意字符串长度为11("hello world"共11个字符) mov eax, 4 mov ebx, 1 mov ecx, teste mov edx, 11 ; 修正原代码的10,避免少输出最后一个'd' int 0x80 exit_program: mov eax, 1 xor ebx, ebx int 0x80
方案2:使用字符串拷贝指令(更高效)
先在.data段定义字符串,再用rep movsb串拷贝指令将字符串复制到.bss的teste变量中:
section .data str_hello db "hello world", 0 ; 定义字符串 str_len equ $ - str_hello ; 计算字符串总长度(含终止符) section .bss teste resb 1024 section .text global main main: ; 配置串拷贝的源、目标和长度 mov esi, str_hello ; 源地址:字符串存储位置 mov edi, teste ; 目标地址:teste变量 mov ecx, str_len-1 ; 拷贝长度:字符串实际字符数(去掉终止符0) cld ; 清零方向标志位,按正向顺序拷贝 rep movsb ; 重复拷贝ecx次字节 ; 系统调用输出 mov eax, 4 mov ebx, 1 mov ecx, teste mov edx, str_len-1 int 0x80 exit_program: mov eax, 1 xor ebx, ebx int 0x80
补充说明
- 原代码中
edx设为10,即便写入完整字符串,也会少输出最后一个字符'd',需修正为11。 - 32位x86汇编中,立即数长度不能超过对应操作数的规格(byte/word/dword),因此无法通过单条
mov指令写入超过4字节的字符串。
内容的提问来源于stack exchange,提问作者spyblock
相关产品推荐
相关产品推荐

