You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
wreck=; cat x.c
typedef unsigned long long uint64;
typedef unsigned int uint32;
void
f(char *b)
{
uint32 off;
off = (uint32)(uint64)b & 7;
if(off) {
b += 8 - off;
}
f(b);
}
wreck=; 6c -S x.c
(x.c:5) TEXT f+0(SB),$32-8
(x.c:5) MOVQ b+0(FP),!!DX
(x.c:9) MOVL DX,!!CX
(x.c:9) ANDL $7,!!CX
(x.c:10) CMPL CX,$0-0
(x.c:10) JEQ ,!!4(PC)
(x.c:11) MOVL $8,!!AX
(x.c:11) SUBL CX,!!AX
(x.c:11) ADDQ AX,!!DX
(x.c:13) MOVQ DX,!!(SP)
(x.c:13) CALL ,!!f+0(SB)
(x.c:13) RET ,!!
(x.c:13) END ,!!
wreck=;
That's correct, but note the MOVL DX, CX at x.c:9.
It is doing the & in CX so that DX (= b) can be used later
in the call to f.
wreck=; 6c -S x.c | grep :$(grep -n '(uint32)(uint64)' x.c | awk -F: '{print $1}')
(x.c:9) MOVL DX,!!CX
(x.c:9) ANDL $7,!!CX
wreck=;
If we make the function more complicated, the MOVL
turns around, so that the original register gets used
for the & and the "copy" (only copying the bottom 32 bits)
gets used later as b.
wreck=; cat y.c
typedef unsigned char byte;
typedef int int32;
typedef unsigned long long uint64;
typedef unsigned int uint32;
void throw(char*);
byte *p[2];
void
f(byte *b)
{
int32 off;
uint64 *bitp;
uint64 woff;
void **vp;
off = (uint32)(uint64)b & 7;
if(off)
b++;
vp = (void**)b;
b = vp[1];
woff = (uint64*)b - (uint64*)p[0];
bitp = (uint64*)p[0] - woff/2 - 1;
if((byte*)bitp < (byte*)p[1] || (byte*)bitp >= (byte*)p[0])
throw("bad bit pointer");
}
wreck=; 6c -S y.c | grep :$(grep -n '(uint32)(uint64)' y.c | awk -F: '{print $1}')
(y.c:17) MOVL AX,!!DX
(y.c:17) ANDL $7,!!AX
wreck=;
The "saved" DX gets used later, having lost the top 32 bits.
The text was updated successfully, but these errors were encountered:
The text was updated successfully, but these errors were encountered: