You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编译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位符号地址相加,地址大小不匹配,直接触发报错。

修复步骤

  1. 替换16位寄存器为32位寄存器:将bx换成ebx,dx换成edx,用于计算偏移量
  2. 调整变量加载指令:用dword访问16位变量(nasm会自动零扩展到32位,不影响计算)
  3. 优化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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 04:20:26