编译Win64汇编程序时遇地址大小相关错误求助
解决Win64汇编中"impossible combination of address sizes"和"invalid effective address"错误
错误原因
Win64采用64位寻址模式,内存地址计算必须使用32位或64位寄存器,不能单独用16位寄存器(如bx、dx)作为偏移量。你代码里的mov ax,word[matriz + bx]用16位bx和64位符号地址相加,地址大小不匹配,直接触发报错。
修复步骤
- 替换16位寄存器为32位寄存器:将bx换成ebx,dx换成edx,用于计算偏移量
- 调整变量加载指令:用
dword访问16位变量(nasm会自动零扩展到32位,不影响计算) - 优化printf参数传递:Win64调用约定中整数参数需用64位寄存器,对short类型的traza做符号扩展后传入rdx
修改后的完整代码
global main extern printf section .data matriz dw 3,4,5 dw 11,6,15 dw 9,5,14 traza dw 0 msjTraza db "La traza es: %hi",0 longElemento dw 2 ; Porque cada elemento es un "word" (2 bytes) longFila dw 6 ; Sale de 2 * 3 (longitud de fila = longitud de elemento * cantidad de columnas) fila dw 1 columna dw 1 section .bss section .text main: ; Calculo la traza call calcularTraza ; Imprimo la traza call imprimirTraza ret calcularTraza: ; Cuando la fila es mayor a 3, entonces el algoritmo ya termino (ya se calculo la traza) cmp word[fila],3 jg regresar ; Calculo la posicion del elemento de la matriz a sumar (los elementos de su diagonal principal) mov ebx, dword[fila] ; 改用32位寄存器ebx dec ebx imul ebx, dword[longFila] ; En ebx queda (i - 1) * longitud de fila, donde "i" es "fila" mov edx, dword[columna] ; 改用32位寄存器edx dec edx imul edx, dword[longElemento] ; En edx queda (j - 1) * longitud del elemento, donde "j" es "columna" add ebx, edx ; Quedandome en "ebx" entonces la posicion del elemento al que debo ir a buscar ( (i-1) * longitudFila + (j-1) * longitudElemento ) ; Voy a buscar el elemento en cuestion y lo guardo en ax mov ax, word[matriz + ebx] ; 用ebx(32位)作为偏移,地址大小匹配 ; Le sumo el elemento a la traza add word[traza],ax ; Incremento en 1 la fila y la columna inc word[fila] inc word[columna] ; Loopeo jmp calcularTraza regresar: ret imprimirTraza: mov rcx, msjTraza movsx rdx, word[traza] ; 符号扩展16位traza到64位rdx,符合Win64调用约定 sub rsp, 32 call printf add rsp, 32 ret
验证编译
用你原来的命令重新编译:
nasm myprogram.asm -f win64 gcc myprogram.obj -o myprogram
此时编译不会再报错,运行程序会输出正确的迹值(3+6+14=23)。
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

