I submitted this bug report:
https://bugs.freepascal.org/view.php?id=32905 which was closed because it was felt I was "asking questions" rather than submitting a bug, even though I explained why I felt it was a bug. So clearly what Florian was trying to say is: you're doing it wrong.
I played around a bit, and looking at the first example:
program Project1;
{$ASMMODE INTEL}
var
r: integer;
begin
asm
MOV r, 7 // crash!
end;
writeln(r);
readln();
end.
it turns out the asm code must be written as "MOV [RIP+r], 7", as x64 uses RIP-relative addressing. Fair enough, and that works fine. But it made me think (as I noted in the bug report): why does the compiler allow you to write code that doesn't make sense
?
Specifically:
1) is there ever any use for loading the absolute address, for example "LEA RAX, r"? I was thinking perhaps for lookup tables there could be, but it wouldn't work very well as the offsets are truncated to 32-bit. For example, in a quick test program "r" is at 0x10000f000, but the instruction is compiled to "LEA RAX, 0xf000".
2) Note that, to add to the fun, you can read from globals just fine: "MOV EAX, r" compiles to (AT&T syntax) "movabs 0x1000f000, %eax", and works as expected - it loads the value of variable "r" into EAX.
3) Given the above, should the compiler not try to help you out by replacing the "r" with "[RIP+offset]" where the code would otherwise make no sense due to offsets being truncated? This would be similar behaviour to stack variables, which are automatically replaced with "[RBP+offset]".
Any opinions? I feel I'm missing something here.
Thanks,
ahydra