Nasm 组装。无法将值移动到堆栈上的局部变量
Nasm assembly. Can't move a value to a local variable on the stack
我试图编写一个 returns 字数组中的最大值的程序。
我已经按照 here 列出的约定分配了局部变量。
但是当我尝试在局部变量中移动一个值时,它给了我这个错误:
invalid combination of opcode and operands
这是我的代码:
greatest:
push ebp
mov ebp, esp
;allocate local variables here
sub esp, 4
;push stuff
push esi
mov ecx, [ebp+12] ;size of the array
mov eax, [ebp+8] ;offset of the array
mov esi, 0 ;counter for accessing elements
mov ebp-4, eax ;error here
l1:
push ecx
mov ecx, [eax + 2*esi] ;get the variable
cmp [ecx], [ebp-4] ;compare values
jb if_2
mov ebp-4, ecx ;error here
if_2:
inc esi
pop ecx
loop l1
mov eax, [ebp-4]
pop esi
mov esp, ebp
pop ebp
ret
任何帮助将不胜感激:)
正如评论中所指出的,您的代码中的问题在于周围事物之间的差异 []
与否。
在 nasm
指示的行中,问题是没有括号。 ebp - 4
是内存中要存储数据的位置,因此必须用括号括起来。
另一个问题是行 cmp [ecx], [ebp - 4]
。这不会编译,因为它试图比较内存中的两个不同项目,位于 ecx
和 ebp - 4
位置,并且你不能用两个不同的内存东西来做(至少一个必须是寄存器/常量)。
但是,无论如何,这并不是您真正想要做的。因为 ecx
存储的是 值 ,而不是 位置 ,所以您确实需要 cmp ecx, [ebp - 4]
。这是正确的。
一旦你改变了这些东西,你的代码就会编译。但是,它不会 运行 正确。虽然 nasm
喜欢它,但仍然存在括号与无括号的问题。
我看到的最后一期还是 mov [ebp - 4], eax
(以前是 mov ebp - 4, eax
)行。虽然 eax
包含列表的偏移量(地址),因此也包含第一个元素的地址,但它不包含该元素本身,因此它也必须用方括号括起来。
然而,只写 mov [ebp - 4], [eax]
会产生与之前类似的错误:nasm
对你大吼大叫,因为你不能在其中包含两个内存。
我们可以通过使用寄存器(例如 esi
)作为临时存储来解决这个问题。 (我选择 esi
因为我们无论如何都要覆盖它,所以我们不必将它存储在堆栈上。)所以这变成:
mov esi, [eax]
mov [ebp-4], esi
mov esi, 0 ; moved this line from above so it's still 0 at the end
所以总而言之,随着变化,这变成了:
greatest:
push ebp
mov ebp, esp
;allocate local variables here
sub esp, 4
;push stuff
push esi
mov ecx, [ebp+12] ;size of the array
mov eax, [ebp+8] ;offset of the array
mov esi, [eax] ;store in esi temporarily
mov [ebp-4], esi ;now we can move it to the local variable
mov esi, 0 ;counter for accessing elements
l1:
push ecx
mov ecx, [eax + 2*esi] ;get the item from the list
cmp ecx, [ebp-4] ;compare values
jb if_2
mov [ebp-4], ecx
if_2:
inc esi
pop ecx
loop l1
mov eax, [ebp-4]
pop esi
mov esp, ebp
pop ebp
ret
我试图编写一个 returns 字数组中的最大值的程序。 我已经按照 here 列出的约定分配了局部变量。 但是当我尝试在局部变量中移动一个值时,它给了我这个错误:
invalid combination of opcode and operands
这是我的代码:
greatest:
push ebp
mov ebp, esp
;allocate local variables here
sub esp, 4
;push stuff
push esi
mov ecx, [ebp+12] ;size of the array
mov eax, [ebp+8] ;offset of the array
mov esi, 0 ;counter for accessing elements
mov ebp-4, eax ;error here
l1:
push ecx
mov ecx, [eax + 2*esi] ;get the variable
cmp [ecx], [ebp-4] ;compare values
jb if_2
mov ebp-4, ecx ;error here
if_2:
inc esi
pop ecx
loop l1
mov eax, [ebp-4]
pop esi
mov esp, ebp
pop ebp
ret
任何帮助将不胜感激:)
正如评论中所指出的,您的代码中的问题在于周围事物之间的差异 []
与否。
在 nasm
指示的行中,问题是没有括号。 ebp - 4
是内存中要存储数据的位置,因此必须用括号括起来。
另一个问题是行 cmp [ecx], [ebp - 4]
。这不会编译,因为它试图比较内存中的两个不同项目,位于 ecx
和 ebp - 4
位置,并且你不能用两个不同的内存东西来做(至少一个必须是寄存器/常量)。
但是,无论如何,这并不是您真正想要做的。因为 ecx
存储的是 值 ,而不是 位置 ,所以您确实需要 cmp ecx, [ebp - 4]
。这是正确的。
一旦你改变了这些东西,你的代码就会编译。但是,它不会 运行 正确。虽然 nasm
喜欢它,但仍然存在括号与无括号的问题。
我看到的最后一期还是 mov [ebp - 4], eax
(以前是 mov ebp - 4, eax
)行。虽然 eax
包含列表的偏移量(地址),因此也包含第一个元素的地址,但它不包含该元素本身,因此它也必须用方括号括起来。
然而,只写 mov [ebp - 4], [eax]
会产生与之前类似的错误:nasm
对你大吼大叫,因为你不能在其中包含两个内存。
我们可以通过使用寄存器(例如 esi
)作为临时存储来解决这个问题。 (我选择 esi
因为我们无论如何都要覆盖它,所以我们不必将它存储在堆栈上。)所以这变成:
mov esi, [eax]
mov [ebp-4], esi
mov esi, 0 ; moved this line from above so it's still 0 at the end
所以总而言之,随着变化,这变成了:
greatest:
push ebp
mov ebp, esp
;allocate local variables here
sub esp, 4
;push stuff
push esi
mov ecx, [ebp+12] ;size of the array
mov eax, [ebp+8] ;offset of the array
mov esi, [eax] ;store in esi temporarily
mov [ebp-4], esi ;now we can move it to the local variable
mov esi, 0 ;counter for accessing elements
l1:
push ecx
mov ecx, [eax + 2*esi] ;get the item from the list
cmp ecx, [ebp-4] ;compare values
jb if_2
mov [ebp-4], ecx
if_2:
inc esi
pop ecx
loop l1
mov eax, [ebp-4]
pop esi
mov esp, ebp
pop ebp
ret