x86_64汇编乘寄存器算地址报invalid operand type错误解决
错误原因
- NASM汇编语法中,
*是编译期运算符号,仅能处理汇编阶段就能确定值的立即数、常量、标号,不支持把寄存器作为运算参数。寄存器里的值是程序运行时才会动态变化的,汇编器编译时根本拿不到edx的实际值,无法完成表达式计算,直接抛出无效操作数错误。 - 另外x86/x86_64硬件原生支持的地址寻址缩放因子只有1、2、4、8四个固定值,就算是运行时计算地址,也不支持直接和160这类非2的小整数次幂的系数做乘法。
修复方案
把编译期计算的写法改成运行时计算偏移,再和基址相加即可,参考代码:
mov edx, 1 ; 先计算偏移量 160 * 当前行号(edx) mov eax, edx imul eax, 160 ; 加上VGA文本缓冲区基址,得到最终地址存入ebx add eax, 0xb8000 mov ebx, eax inc edx
- 如果后续是要直接操作显存对应地址的内容,也可以不用单独把地址存到ebx,算完偏移后直接用基址加偏移的寻址方式访问内存即可:
mov edx, 1 mov esi, edx imul esi, 160 ; 示例:往目标显存位置写入白底黑字的字符'A' mov word [0xb8000 + esi], 0x0f41 inc edx
提示:如果你编写的是64位长模式下的裸机程序,只要没有做特殊的地址映射,0xb8000作为VGA文本缓冲区的物理地址映射后可以正常访问;如果开启了高半区内核映射,替换为对应的虚拟地址即可。
内容的提问来源于stack exchange,提问作者Markian
相关产品推荐
相关产品推荐

