汇编开发中能否修改.data段存储的值?对应代码报错如何解决
报错原因
- 警告
character constant too long:你代码中使用的'Hello, world.'是13字节的字符串常量,32位x86汇编中单引号包裹的字符常量最长仅支持4字节,超出长度限制就会触发该警告。 - 错误
invalid combination of opcode and operands:有两个问题导致该错误:- x86的
mov指令本身不支持直接将超长立即数批量写入连续内存的操作组合 - 写法
mov msg, xxx中msg本质是代表字符串起始地址的立即数,立即数不能作为赋值操作的左值,即使你要写入内存也需要用方括号[]包裹地址表示取内存位置操作。
- x86的
实现修改的方案
你只需要修改字符串末尾的单个感叹号,不需要重写整个字符串,直接定位到感叹号对应的内存偏移修改单字节即可:
原字符串'Hello, world!',0xa中,!的位置相对于msg起始地址的偏移为12(下标从0开始计数),将出错的那行代码替换为:
mov byte [msg + 12], '.'
该行代码的含义:
byte指定本次操作的操作数长度为1字节[msg + 12]表示操作的是msg起始地址偏移12位置的内存空间,也就是原!的存储位置'.'是要写入的目标ASCII字符
修改后完整可运行代码
section .text global _start _start: ; 替换末尾的!为. mov byte [msg + 12], '.' mov edx, len ; 消息长度 mov ecx, msg ; 要写入的消息 mov ebx, 1 ; 标准输出 mov eax, 4 ; 系统调用号(sys_write) int 0x80 ; 调用内核 mov eax, 1 ; 系统调用号(sys_exit) int 0x80 ; 调用内核 section .data msg db 'Hello, world!',0xa ; 原始字符串 len equ $ - msg ; 字符串长度
如果你确实需要批量替换整个长字符串,需要逐字节拷贝或者使用rep movsb等串操作指令完成,无法通过单次mov指令实现。
内容的提问来源于stack exchange,提问作者user15446500
相关产品推荐
相关产品推荐

