unsigned short xx = -1;
printf("%d", xx);
unsigned int yy = -1;
printf("%d", yy);
這段程式碼編譯成彙編之後得到如下程式碼
call ___main
movw $-1, 26(%esp)
movzwl 26(%esp), %eax
movl %eax, 4(%esp)
movl $LC0, (%esp)
call _printf // 第一個printf
movl $-1, 28(%esp)
movl 28(%esp), %eax
call _printf // 第二個printf
注意兩個printf呼叫之前的兩端程式碼,不同之處在於將-1傳遞給printf的時候的資料傳遞指令
第一個用的是movzwl 第二個用的是movl
movzwl是將16位的資料複製到32位的低16位空間中,並且高位16未補0
這樣不難得出,最後傳到printf裡面的數字假設是M,它的高16位是0,低16為都是1,解釋為int就是65535了。
而movl都是同樣的32位操作,所以沒有任何轉化,結果還是-1。
unsigned short xx = -1;
printf("%d", xx);
unsigned int yy = -1;
printf("%d", yy);
這段程式碼編譯成彙編之後得到如下程式碼
call ___main
movw $-1, 26(%esp)
movzwl 26(%esp), %eax
movl %eax, 4(%esp)
movl $LC0, (%esp)
call _printf // 第一個printf
movl $-1, 28(%esp)
movl 28(%esp), %eax
movl %eax, 4(%esp)
movl $LC0, (%esp)
call _printf // 第二個printf
注意兩個printf呼叫之前的兩端程式碼,不同之處在於將-1傳遞給printf的時候的資料傳遞指令
第一個用的是movzwl 第二個用的是movl
movzwl是將16位的資料複製到32位的低16位空間中,並且高位16未補0
這樣不難得出,最後傳到printf裡面的數字假設是M,它的高16位是0,低16為都是1,解釋為int就是65535了。
而movl都是同樣的32位操作,所以沒有任何轉化,結果還是-1。