Bug 21101 – Inline Assembler: 32 bit values are truncated to 32 bits

Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
All
Creation time
2020-08-02T08:59:17Z
Last change time
2020-08-25T07:39:38Z
Keywords
iasm, wrong-code
Assigned to
No Owner
Creator
Walter Bright
See also
https://issues.dlang.org/show_bug.cgi?id=6459

Comments

Comment #0 by bugzilla — 2020-08-02T08:59:17Z
Bug report transferred from https://issues.dlang.org/show_bug.cgi?id=6459 : Another negative immediate value issue: mov EAX,-2; /* line 1 */ mov EAX,0xFFFFFFFE; /* line 2 */ mov EAX,0xFFFFFFFFFFFFFFFE; /* line 3 */ mov R8D,-2; /* line 4 */ mov R8D,0xFFFFFFFE; /* line 5 */ mov R8D,0xFFFFFFFFFFFFFFFE; /* line 6 */ Anybody writing line 3 or 6 has probably made a mistake, but line 3 is accepted as equivalent to 1 and 2, and line 6 is accepted as equivalent to 4 and 5 (as 32 bit loads clear the top 32 bits of the equivalent 64 bit register they do not sign extend).
Comment #1 by bugzilla — 2020-08-25T07:39:38Z
The problem is, being assembler code, there is no distinction between signed and unsigned values for immediate values. The instruction semantics determine if it is signed or unsigned. The values are all computed as 64 bit integers. Hence, -2 is indistinguishable from 0xFFFFFFFFFFFFFFFE. Whether it gets truncated or sign extended is determined by the instruction, there is no concept of a signed or unsigned immediate value. It's working as designed.