C/C++ 中结构体输出异常的原因(存储结构)
typedef struct{
double d_num;
char c;
int num;
}Node;
int main(){
Node n = {1.0000, 'a', 3};
printf("%d %c %d\n", n.d_num, n.c, n.num);
}
其中应解释为64位double的部分被解释为32位整型。运行以上会显示97 0, 怎么用存储结构来解释这种异常?
nowten
11 years, 11 months ago
Answers
你用的是 32 位系统。我们 gcc -S 看下它的汇编:
1 fld1
2 fstpl 32(%esp)
3 movb $97, 40(%esp)
4 movl $3, 44(%esp)
5 movl 44(%esp), %edx
6 movzbl 40(%esp), %eax
7 movsbl %al, %eax
8 fldl 32(%esp)
9 movl %edx, 16(%esp)
10 movl %eax, 12(%esp)
11 fstpl 4(%esp)
12 movl $.LC1, (%esp)
13 call printf
14 movl $0, %eax
-
11 行,存入浮点数到地址
4(%esp)
,这是printf
的第一个参数。通过 gdb 可以看到其十六进制表示为0x00000000 0x3ff00000
。把它的前一个字作为一个整数,即「0」; -
10 行,
%eax
的值是把40(%esp)
的低字节(第 6、7 行)弄过来的,即'a'
,也就是打印出来的「97」; -
而
printf
中%c
对应的那个'\0'
是怎么来的呢?它是那个浮点数的后一个字的最低字节。
64 位系统上函数调用方式不一样。结果是
97, \3, 97
。其中第三个「97」是编译器以为那个寄存器
printf
函数不会用所以残留的之前的值,因为它的第二个参数是浮点数,通过
%xmm0
寄存器传递的,但是
printf
认为没有浮点数所以不使用。不同参数所使用的寄存器没什么规律,如下:
The first 6 integer parameters in a function under Linux are passed in registers rdi , rsi, rdx, rex, r8 and r9
Nodoubt
answered 11 years, 11 months ago