| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include <stdio.h> int main(void) { int n = 7; printf("n: %d", n); printf("&n: %x", &n); printf("&n: %lx", &n); printf("포인터 하나당 크기는 %ld 바이트 ", sizeof(void *)); printf("&n: %p", &n); printf("================================ "); printf("&n %p", &n); printf("&n %p", (void*)((int)&n << 4)); printf("&n %p", (void*)((int)&n << 8)); printf("&n %p", (void*)((int)&n << 12)); return 0; } |
&n은 정수를 가리키는 포인터인데, (int)로 인해 32비트 정수가 되어버림.
32비트인 상태로 비트쉬프트를 하니 앞의 8자리는 싹 잘린 채로 비트쉬프트를 하게 되고, (shl rax, 4 가 아닌 shl eax, 4)
(void*) 형변환 때문에 어셈블리에 cdqe가 들어가고, DWORD를 QWORD로 변환할때 2의 보수까지 적용되어 앞에 0xffff가 붙는 수도 있음.
해결책
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #include <stdio.h> #include <stdint.h> int main(void) { int n = 7; printf("n: %d", n); printf("&n: %x", &n); printf("&n: %lx", &n); printf("포인터 하나당 크기는 %ld 바이트 ", sizeof(void *)); printf("&n: %p", &n); printf("================================ "); printf("&n %p", &n); printf("&n %p", (void*)((uint64_t)&n << 4)); printf("&n %p", (void*)((uint64_t)&n << 8)); printf("&n %p", (void*)((uint64_t)&n << 12)); return 0; } |
DWORD -> QWORD 와는 상관없는 문제야, 왜냐하면 C에는 DWORD QWORD 가 없거든 이건 어셈이나 윈 프로그래밍에서나 쓰이는 타입이잖아. 이건 언어 규칙 문제지 4바이트니 8바이트니 하는 문제가 아님, 저거를 UINT64 로 처리하면 앞에 0000이 안 붙고 8바이트 전부 그대로 따라 옴. 질문자가 원하는 결과를 얻으려면 int 대신 unsigned int 를 쓰는 게 맞음
한마디로 설명하면 C언어 문법문제야, C언어에서는 int 를 8바이트 포인터로 변환할때 앞 4바이트에 f를 채우고 uint32일때는 0으로 채움
ㄴ 디버거 사진 첨부함
형들 이해됨! 정리해서 다시 한번 글 올릴게
근데 질문자는 unsignd int 로 하면 안 된다고 하네 ㅋㅋㅋ 뭐지 난 되는데 이상하다
unsigned int 로 해야한다는건 잘 모르겠으...
정리해서 다시 올려볼게