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]。这不会编译,因为它试图比较内存中的两个不同项目,位于 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