cdq(0x12345678) bit 31 is set (1)
No, it's not ... the highest bit set is bit 28:
1 2 3 4 5 6 7 8
0001 0010 0011 0100 0101 0110 0111 1000
^ ^
| |
31 28
You code should work, but I would use
if( eax & (1U << 31) ) edx = 0xFFFFFFFF;
since it's a bit more direct and it shifts a constant rather than a variable so does less work at run time (although an optimizing compiler should produce the same code for both).
Actually I would write something like
int cdq(int eax)
{
return eax < 0? -1 : 0;
}
By the way, your code doesn't actually implement cdq because your eax and edx variables are not the hardware eax and edx registers. And it's really not a very good idea to replicate ASM instructions as C functions anyway ... C has its own features for doing these sorts of things, e.g.,
int32_t foo = -0x12345678;
int64_t bar = (int64_t)foo;