简体   繁体   中英

Nasm assembly. Can't move a value to a local variable on the stack

I tried to write a procedure that returns greatest value in a word array. I've allocated local variable by convention listed here . But when I try to move a value in local variable it gives me this error:

invalid combination of opcode and operands

Here is my code:

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

Any help would be greatly appreciated :)

As pointed out in the comments, the problems in your code are with the difference between surrounding things by [] and not.

On the lines indicated by nasm , the issue is not having brackets. ebp - 4 is a location in memory that you want to store the data to, so you have to surround it with brackets.

Another issue is with the line cmp [ecx], [ebp - 4] . This won't compile because it's trying to compare two different items in memory, at locations ecx and ebp - 4 , and you can't do it with two different memory things (at least one has to be a register / constant).

However, this is not really what you would like to do anyway. Because ecx stores the value , not the location , you really want cmp ecx, [ebp - 4] . This is correct.

Once you change these things, your code will compile. However, it will not run correctly. While nasm likes it, there are still issues with brackets vs no brackets.

The last issue I see is, again, with the mov [ebp - 4], eax (previously mov ebp - 4, eax ) line. While eax contains the offset (address) of the list, and therefore the address of the first element, it does not contain that element itself, so it, too, must be surrounded with brackets.

However, just writing mov [ebp - 4], [eax] produces a similar error to before: nasm yells at you because you can't have two memory things in it.

We can fix this by using a register (eg esi ) as a temporary storage. (I chose esi because we're overwriting it anyway, so we don't have to store it on the stack.) So this becomes:

mov esi, [eax]
mov [ebp-4], esi
mov esi, 0        ; moved this line from above so it's still 0 at the end

So all in all, with the changes this becomes:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM