错误C2432对';中16位数据的非法引用;第二个操作数';关于asm
在VisualStudio中,我在用C编译asm时遇到了这个错误。有人知道这段代码有什么问题吗?我什么都试过了,但都没用。我正在尝试在汇编中实现冒泡排序错误C2432对';中16位数据的非法引用;第二个操作数';关于asm,c,visual-studio,assembly,inline-assembly,32-bit,C,Visual Studio,Assembly,Inline Assembly,32 Bit,在VisualStudio中,我在用C编译asm时遇到了这个错误。有人知道这段代码有什么问题吗?我什么都试过了,但都没用。我正在尝试在汇编中实现冒泡排序 unsigned short i = 0; unsigned short j = 0; unsigned short max = short(N-2); unsigned short tab[5]; tab[0] = 54; tab[1] = 123; tab[2] = 342; tab[3] = 5436; tab[4] = 1234;
unsigned short i = 0;
unsigned short j = 0;
unsigned short max = short(N-2);
unsigned short tab[5];
tab[0] = 54;
tab[1] = 123;
tab[2] = 342;
tab[3] = 5436;
tab[4] = 1234;
unsigned short a = 0;
__asm {
loop1:
inc i
mov j, 0
mov si, tab
loop2:
mov ax, [si] // <- Error C2432 on this line
mov a, ax
inc j
mov ax, j
mov bx, max
cmp ax, bx
jz cdnloop2
loop loop2
cdnloop2:
mov ax, i
mov bx, max
cmp ax, bx
jz endof
loop loop1
endof :
}
无符号短i=0;
无符号短j=0;
无符号短路最大值=短路(N-2);
无符号短制表符[5];
表[0]=54;
表[1]=123;
表[2]=342;
表[3]=5436;
表[4]=1234;
无符号短a=0;
__asm{
循环1:
公司一
movj,0
mov si,制表符
循环2:
mov ax,[si]/用谷歌搜索错误消息。答案是(第一次谷歌点击)
对“标识符”中16位数据的非法引用
16位寄存器用作索引或基址寄存器。编译器
不支持引用16位数据。不能引用16位寄存器
编译32位代码时用作索引或基寄存器
第一段有点混乱,因为听起来问题是16位操作数大小,而不是16位地址大小。但第二段明确指出:它拒绝使用地址大小前缀来组装类似于mov ax,[si]
,因为在内联asm中,忽略地址的大写16不是一件有用的事情
他们已经决定,在编译时捕获这样的输入错误比发出崩溃的代码要好
可能只需将行更改为mov ax,[tab]
。将地址存储在esi
中不会获得任何好处,因为您不需要修改它。内存地址是32位。(如果您将程序编译为64位,则为64位)mov ax,word ptr[si]
解决它?地址寄存器必须是32位或64位。使用mov ax、[esi]
或mov ax、[rsi]
@immibis从技术上讲mov ax,[si]
在32位模式下允许使用地址大小覆盖前缀(66 67 8B 04
)。可能没有任何意义,但这是允许的。@Dirkwolfganglomp。在这种情况下,mov ax,[esi]
通常使用esi(而不是SI)。所讨论的代码不是64位的,因为Visual Studio根本不允许64位内联汇编。这几乎消除了mov ax,[rsi]
作为替代。@Joshua:是的,它是32位,但不是64位。就像Jester和Michael Petch在评论中说的那样。67 66 8b 04 mov ax,WORD PTR[si]
。地址大小和操作数大小前缀。这是yasm-f elf32和&objdump-Mintel-d的反汇编输出。