纳斯姆集会。无法将值移动到堆栈上的局部变量

时间:2017-05-01 19:21:06

标签: assembly nasm

我尝试编写一个在单词数组中返回最大值的过程。 我已根据列出的约定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

非常感谢任何帮助:)

1 个答案:

答案 0 :(得分:0)

正如评论中所指出的,代码中的问题与[]之间的差异有关。

nasm指示的行上,问题没有括号。 ebp - 4是内存中要存储数据的位置,因此您必须用括号括起来。

另一个问题是行cmp [ecx], [ebp - 4]。这不会编译,因为它试图比较内存中ecxebp - 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