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".