我尝试编写一个在单词数组中返回最大值的过程。 我已根据列出的约定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
非常感谢任何帮助:)
答案 0 :(得分:0)
正如评论中所指出的,代码中的问题与[]
之间的差异有关。
在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