x86汇编内存寻址:乘法打印代码的两类技术疑问
x86汇编打印乘积结果的疑问解答
先贴出你的汇编代码:
section .text global _start _start: mov ecx, [num1] mov eax, [num2] mul ecx mov [result], eax mov edx, 1 mov ecx, result ; 1. 为何将此处的result替换为eax后无法正常运行?为何必须先创建未初始化变量result存储值再传入ecx? ; 2. 为何此处必须使用result而非之前代码行中使用的[result]? mov ebx, 1 mov eax, 4 int 0x80 mov eax, 1 int 0x80 section .data num1 db 2 num2 db 28 section .bss result resb 1
疑问1:替换成eax无法运行,必须用result存储的原因
Linux的int 0x80系统调用中,eax=4对应的是write函数,它对ecx的要求是要输出内容的内存缓冲区起始地址,而非直接的数值。
- 你把乘积结果存在
eax里时,eax的值是56(对应ASCII的'8'),如果直接mov ecx, eax,ecx里就会是56。这时候write会尝试访问内存地址0x38(56的十六进制)的内容,但这个地址不属于你的进程合法内存空间,会直接触发段错误导致程序崩溃。 - 而
result是你在.bss段申请的1字节内存空间,把eax里的数值存到[result]后,result本身代表这块内存的地址,传给ecx后,write就能正确读取这块内存里的56,输出对应的字符。
疑问2:必须用result而非[result]的原因
- 在汇编语法里,
result是这个变量的符号地址,直接写它就是取这块内存的地址值;而[result]是取这个地址里存储的内容(也就是你之前存的56)。 - 前面说了
write需要的是缓冲区的地址,不是内容。如果写mov ecx, [result],ecx里又会是56,和疑问1里直接传eax的错误一样,会导致访问非法内存地址,程序崩溃。
内容的提问来源于stack exchange,提问作者ʎuuoɥɾ
相关产品推荐
相关产品推荐

