Pregunta

I am trying to get my head around some inline ASM but for some reason this isn't behaving as I would have expected. Why isn't this setting the value of x equal to 62?

#include <stdio.h>

int main()
{
    int x = 525;
    int* y = &x;

    _asm
    {
        mov eax, 62
        mov [y], eax
    }

    printf("%i", x);
    getchar();
    return 0;
}

The code results in 525 being output. I expected it to be 62.

¿Fue útil?

Solución

There's a perfectly excusable misunderstanding here:

surely [y] would mean [0xCCCCCCCC] (assuming the address of x was 0xCCCCCCCC)

In high-level theory, yes. The trouble is, in actual assembly [0xCCCCCCCC] makes no sense - the CPU can't dereference a memory address directly - it can only load a value from that address into a register, then dereference that.

Similarly, since y is a variable, not a register, it's implicitly treated as an address1 i.e. y inside the asm block is the equivalent of &y in the C code outside2. As you can see by stepping through in a debugger, what happened is the assembler simply ignored the brackets that don't make sense (rather than throwing a helpful error) and assembled the equivalent of mov y, eax.

The way to get what you expect would be something like this:

asm {
    mov eax, 62
    mov edx, y
    mov [edx], eax
}

[1] this clearly isn't GCC. GCC extended asm is a whole different ball game...

[2] somewhat of a simplification - it's an "address" from a C point of view, but in assembly context it's a memory operand, which is really more like the use of an address. When I compiled this, y came out as [ebp-20], which from the high level view is "an address on the stack".

Otros consejos

You are loadig the address of x into y. Then you are storing 62 in the address (again!) of the variable y -- that's what the [..] syntax means. So you are not modifying the variable x but rather the value stored at *(*y). (And it's a small wonder that does not crash your program.)

You probably want

mov [&y], eax

(if your compiler accepts that syntax).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top