#include<stdio.h>
int main()
{
char a;
int b;
printf("%x\n%x\n", &a, &b);
return 0;
}
编译(x86)会有警告,不过没关系,不过打出来的地址就得把你吓一跳了。
14 个解决方案
#1
用法有问题,没什么神奇的,打印地址用%p:
printf("%p\n%p\n", &a, &b);
printf("%p\n%p\n", &a, &b);
#2
LZ想表达什么?打出的地址是什么?
#3
同志一样的这种情况,a的地址比 b 高的“多”,一种解释是ubuntu系统入栈是倒增的,另外一种就是gcc故意这么干的。
#4
080483e4 <main>:
80483e4: 55 push %ebp
80483e5: 89 e5 mov %esp,%ebp
80483e7: 83 e4 f0 and $0xfffffff0,%esp
80483ea: 83 ec 20 sub $0x20,%esp
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
80483f9: 00
80483fa: b8 f0 84 04 08 mov $0x80484f0,%eax
80483ff: 8d 54 24 18 lea 0x18(%esp),%edx
8048403: 89 54 24 08 mov %edx,0x8(%esp)
8048407: 8d 54 24 1f lea 0x1f(%esp),%edx
804840b: 89 54 24 04 mov %edx,0x4(%esp)
804840f: 89 04 24 mov %eax,(%esp)
8048412: e8 e9 fe ff ff call 8048300 <printf@plt>
8048417: b8 00 00 00 00 mov $0x0,%eax
804841c: c9 leave
804841d: c3 ret
804841e: 90 nop
804841f: 90 nop
main段的反汇编奉上,不知道注意到
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
这两行没有,所以我才说它神奇
#5
VC 的 Debug 版本也经常会在变量中间插入很多的 0xcc 空隙, 用来检查你对变量的写入是否有越界.
#6
080483e4 <main>:
80483e4: 55 push %ebp
80483e5: 89 e5 mov %esp,%ebp
80483e7: 83 e4 f0 and $0xfffffff0,%esp
80483ea: 83 ec 20 sub $0x20,%esp
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
80483f9: 00
80483fa: b8 f0 84 04 08 mov $0x80484f0,%eax
80483ff: 8d 54 24 18 lea 0x18(%esp),%edx
8048403: 89 54 24 08 mov %edx,0x8(%esp)
8048407: 8d 54 24 1f lea 0x1f(%esp),%edx
804840b: 89 54 24 04 mov %edx,0x4(%esp)
804840f: 89 04 24 mov %eax,(%esp)
8048412: e8 e9 fe ff ff call 8048300 <printf@plt>
8048417: b8 00 00 00 00 mov $0x0,%eax
804841c: c9 leave
804841d: c3 ret
804841e: 90 nop
804841f: 90 nop
main段的反汇编奉上,不知道注意到
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
这两行没有,所以我才说它神奇
这两行有何神奇之处? 帮你把变量初始化为 0 了吗, 有什么大不了的呀?
#7
VC 的 Debug 版本也经常会在变量中间插入很多的 0xcc 空隙, 用来检查你对变量的写入是否有越界.
我的是gcc -。- VC神马的别乱入
#8
080483e4 <main>:
80483e4: 55 push %ebp
80483e5: 89 e5 mov %esp,%ebp
80483e7: 83 e4 f0 and $0xfffffff0,%esp
80483ea: 83 ec 20 sub $0x20,%esp
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
80483f9: 00
80483fa: b8 f0 84 04 08 mov $0x80484f0,%eax
80483ff: 8d 54 24 18 lea 0x18(%esp),%edx
8048403: 89 54 24 08 mov %edx,0x8(%esp)
8048407: 8d 54 24 1f lea 0x1f(%esp),%edx
804840b: 89 54 24 04 mov %edx,0x4(%esp)
804840f: 89 04 24 mov %eax,(%esp)
8048412: e8 e9 fe ff ff call 8048300 <printf@plt>
8048417: b8 00 00 00 00 mov $0x0,%eax
804841c: c9 leave
804841d: c3 ret
804841e: 90 nop
804841f: 90 nop
main段的反汇编奉上,不知道注意到
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
这两行没有,所以我才说它神奇
这两行有何神奇之处? 帮你把变量初始化为 0 了吗, 有什么大不了的呀?
你不觉得那2个地址差的太远了吗? 而且打印出的结果char 的地址比 int 的大
#9
标准并没有规定分配地址的顺序与变量声明的顺序一致。
080483e4 <main>:
80483e4: 55 push %ebp
80483e5: 89 e5 mov %esp,%ebp
80483e7: 83 e4 f0 and $0xfffffff0,%esp
80483ea: 83 ec 20 sub $0x20,%esp
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
80483f9: 00
80483fa: b8 f0 84 04 08 mov $0x80484f0,%eax
80483ff: 8d 54 24 18 lea 0x18(%esp),%edx
8048403: 89 54 24 08 mov %edx,0x8(%esp)
8048407: 8d 54 24 1f lea 0x1f(%esp),%edx
804840b: 89 54 24 04 mov %edx,0x4(%esp)
804840f: 89 04 24 mov %eax,(%esp)
8048412: e8 e9 fe ff ff call 8048300 <printf@plt>
8048417: b8 00 00 00 00 mov $0x0,%eax
804841c: c9 leave
804841d: c3 ret
804841e: 90 nop
804841f: 90 nop
main段的反汇编奉上,不知道注意到
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
这两行没有,所以我才说它神奇
#10
标准并没有规定分配地址的顺序与变量声明的顺序一致。
080483e4 <main>:
80483e4: 55 push %ebp
80483e5: 89 e5 mov %esp,%ebp
80483e7: 83 e4 f0 and $0xfffffff0,%esp
80483ea: 83 ec 20 sub $0x20,%esp
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
80483f9: 00
80483fa: b8 f0 84 04 08 mov $0x80484f0,%eax
80483ff: 8d 54 24 18 lea 0x18(%esp),%edx
8048403: 89 54 24 08 mov %edx,0x8(%esp)
8048407: 8d 54 24 1f lea 0x1f(%esp),%edx
804840b: 89 54 24 04 mov %edx,0x4(%esp)
804840f: 89 04 24 mov %eax,(%esp)
8048412: e8 e9 fe ff ff call 8048300 <printf@plt>
8048417: b8 00 00 00 00 mov $0x0,%eax
804841c: c9 leave
804841d: c3 ret
804841e: 90 nop
804841f: 90 nop
main段的反汇编奉上,不知道注意到
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
这两行没有,所以我才说它神奇
所以我觉得扯蛋啊,之前用的工具都是按照默认顺序排的,最多给你来个字节对齐,这种玩法还没见过。环境是ubuntu12.04 lts gcc 4.6.3 虽然这个问题争论下去根本没意义,因为变量只要有空间能访问的到,存放顺序无所谓. 但不得不说挺扯蛋的.
#11
还是在验证MIPS非字节对齐访问问题的时候无意间用x86的编译器编错了发现的.
#12
扯完就轻松了,所以不按照规范写代码是很有隐患的。
标准并没有规定分配地址的顺序与变量声明的顺序一致。
080483e4 <main>:
80483e4: 55 push %ebp
80483e5: 89 e5 mov %esp,%ebp
80483e7: 83 e4 f0 and $0xfffffff0,%esp
80483ea: 83 ec 20 sub $0x20,%esp
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
80483f9: 00
80483fa: b8 f0 84 04 08 mov $0x80484f0,%eax
80483ff: 8d 54 24 18 lea 0x18(%esp),%edx
8048403: 89 54 24 08 mov %edx,0x8(%esp)
8048407: 8d 54 24 1f lea 0x1f(%esp),%edx
804840b: 89 54 24 04 mov %edx,0x4(%esp)
804840f: 89 04 24 mov %eax,(%esp)
8048412: e8 e9 fe ff ff call 8048300 <printf@plt>
8048417: b8 00 00 00 00 mov $0x0,%eax
804841c: c9 leave
804841d: c3 ret
804841e: 90 nop
804841f: 90 nop
main段的反汇编奉上,不知道注意到
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
这两行没有,所以我才说它神奇
所以我觉得扯蛋啊,之前用的工具都是按照默认顺序排的,最多给你来个字节对齐,这种玩法还没见过。环境是ubuntu12.04 lts gcc 4.6.3 虽然这个问题争论下去根本没意义,因为变量只要有空间能访问的到,存放顺序无所谓. 但不得不说挺扯蛋的.
#13
标准并没有规定分配地址的顺序与变量声明的顺序一致。
080483e4 <main>:
80483e4: 55 push %ebp
80483e5: 89 e5 mov %esp,%ebp
80483e7: 83 e4 f0 and $0xfffffff0,%esp
80483ea: 83 ec 20 sub $0x20,%esp
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
80483f9: 00
80483fa: b8 f0 84 04 08 mov $0x80484f0,%eax
80483ff: 8d 54 24 18 lea 0x18(%esp),%edx
8048403: 89 54 24 08 mov %edx,0x8(%esp)
8048407: 8d 54 24 1f lea 0x1f(%esp),%edx
804840b: 89 54 24 04 mov %edx,0x4(%esp)
804840f: 89 04 24 mov %eax,(%esp)
8048412: e8 e9 fe ff ff call 8048300 <printf@plt>
8048417: b8 00 00 00 00 mov $0x0,%eax
804841c: c9 leave
804841d: c3 ret
804841e: 90 nop
804841f: 90 nop
main段的反汇编奉上,不知道注意到
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
这两行没有,所以我才说它神奇
所以我觉得扯蛋啊,之前用的工具都是按照默认顺序排的,最多给你来个字节对齐,这种玩法还没见过。环境是ubuntu12.04 lts gcc 4.6.3 虽然这个问题争论下去根本没意义,因为变量只要有空间能访问的到,存放顺序无所谓. 但不得不说挺扯蛋的.
那是你没仔细看过,在x86系列机上一般编译器的编译结果都是让局部自动变量晚声明的地址更低,因为栈本身就是自上向下分配内存的。
#14
080483e4 <main>:
80483e4: 55 push %ebp
80483e5: 89 e5 mov %esp,%ebp
80483e7: 83 e4 f0 and $0xfffffff0,%esp
80483ea: 83 ec 20 sub $0x20,%esp
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
80483f9: 00
80483fa: b8 f0 84 04 08 mov $0x80484f0,%eax
80483ff: 8d 54 24 18 lea 0x18(%esp),%edx
8048403: 89 54 24 08 mov %edx,0x8(%esp)
8048407: 8d 54 24 1f lea 0x1f(%esp),%edx
804840b: 89 54 24 04 mov %edx,0x4(%esp)
804840f: 89 04 24 mov %eax,(%esp)
8048412: e8 e9 fe ff ff call 8048300 <printf@plt>
8048417: b8 00 00 00 00 mov $0x0,%eax
804841c: c9 leave
804841d: c3 ret
804841e: 90 nop
804841f: 90 nop
main段的反汇编奉上,不知道注意到
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
这两行没有,所以我才说它神奇
这两行有何神奇之处? 帮你把变量初始化为 0 了吗, 有什么大不了的呀?
你不觉得那2个地址差的太远了吗? 而且打印出的结果char 的地址比 int 的大
这也没什么好神奇的, 你如果去掉 printf 语句, 也就是不使用变量, 再去观察反汇编, 会发现变量的分配顺序和使用过变量的时候刚好相反. 这岂不是更神奇?
#1
用法有问题,没什么神奇的,打印地址用%p:
printf("%p\n%p\n", &a, &b);
printf("%p\n%p\n", &a, &b);
这段代码"老"神奇了:
#include<stdio.h>
int main()
{
char a;
int b;
printf("%x\n%x\n", &a, &b);
return 0;
}
编译(x86)会有警告,不过没关系,不过打出来的地址就得把你吓一跳了。
#2
LZ想表达什么?打出的地址是什么?
#3
用法有问题,没什么神奇的,打印地址用%p:
printf("%p\n%p\n", &a, &b);
这段代码"老"神奇了:
#include<stdio.h>
int main()
{
char a;
int b;
printf("%x\n%x\n", &a, &b);
return 0;
}
编译(x86)会有警告,不过没关系,不过打出来的地址就得把你吓一跳了。
同志一样的这种情况,a的地址比 b 高的“多”,一种解释是ubuntu系统入栈是倒增的,另外一种就是gcc故意这么干的。
#4
080483e4 <main>:
80483e4: 55 push %ebp
80483e5: 89 e5 mov %esp,%ebp
80483e7: 83 e4 f0 and $0xfffffff0,%esp
80483ea: 83 ec 20 sub $0x20,%esp
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
80483f9: 00
80483fa: b8 f0 84 04 08 mov $0x80484f0,%eax
80483ff: 8d 54 24 18 lea 0x18(%esp),%edx
8048403: 89 54 24 08 mov %edx,0x8(%esp)
8048407: 8d 54 24 1f lea 0x1f(%esp),%edx
804840b: 89 54 24 04 mov %edx,0x4(%esp)
804840f: 89 04 24 mov %eax,(%esp)
8048412: e8 e9 fe ff ff call 8048300 <printf@plt>
8048417: b8 00 00 00 00 mov $0x0,%eax
804841c: c9 leave
804841d: c3 ret
804841e: 90 nop
804841f: 90 nop
main段的反汇编奉上,不知道注意到
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
这两行没有,所以我才说它神奇
#5
VC 的 Debug 版本也经常会在变量中间插入很多的 0xcc 空隙, 用来检查你对变量的写入是否有越界.
#6
080483e4 <main>:
80483e4: 55 push %ebp
80483e5: 89 e5 mov %esp,%ebp
80483e7: 83 e4 f0 and $0xfffffff0,%esp
80483ea: 83 ec 20 sub $0x20,%esp
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
80483f9: 00
80483fa: b8 f0 84 04 08 mov $0x80484f0,%eax
80483ff: 8d 54 24 18 lea 0x18(%esp),%edx
8048403: 89 54 24 08 mov %edx,0x8(%esp)
8048407: 8d 54 24 1f lea 0x1f(%esp),%edx
804840b: 89 54 24 04 mov %edx,0x4(%esp)
804840f: 89 04 24 mov %eax,(%esp)
8048412: e8 e9 fe ff ff call 8048300 <printf@plt>
8048417: b8 00 00 00 00 mov $0x0,%eax
804841c: c9 leave
804841d: c3 ret
804841e: 90 nop
804841f: 90 nop
main段的反汇编奉上,不知道注意到
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
这两行没有,所以我才说它神奇
这两行有何神奇之处? 帮你把变量初始化为 0 了吗, 有什么大不了的呀?
#7
VC 的 Debug 版本也经常会在变量中间插入很多的 0xcc 空隙, 用来检查你对变量的写入是否有越界.
我的是gcc -。- VC神马的别乱入
#8
080483e4 <main>:
80483e4: 55 push %ebp
80483e5: 89 e5 mov %esp,%ebp
80483e7: 83 e4 f0 and $0xfffffff0,%esp
80483ea: 83 ec 20 sub $0x20,%esp
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
80483f9: 00
80483fa: b8 f0 84 04 08 mov $0x80484f0,%eax
80483ff: 8d 54 24 18 lea 0x18(%esp),%edx
8048403: 89 54 24 08 mov %edx,0x8(%esp)
8048407: 8d 54 24 1f lea 0x1f(%esp),%edx
804840b: 89 54 24 04 mov %edx,0x4(%esp)
804840f: 89 04 24 mov %eax,(%esp)
8048412: e8 e9 fe ff ff call 8048300 <printf@plt>
8048417: b8 00 00 00 00 mov $0x0,%eax
804841c: c9 leave
804841d: c3 ret
804841e: 90 nop
804841f: 90 nop
main段的反汇编奉上,不知道注意到
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
这两行没有,所以我才说它神奇
这两行有何神奇之处? 帮你把变量初始化为 0 了吗, 有什么大不了的呀?
你不觉得那2个地址差的太远了吗? 而且打印出的结果char 的地址比 int 的大
#9
标准并没有规定分配地址的顺序与变量声明的顺序一致。
080483e4 <main>:
80483e4: 55 push %ebp
80483e5: 89 e5 mov %esp,%ebp
80483e7: 83 e4 f0 and $0xfffffff0,%esp
80483ea: 83 ec 20 sub $0x20,%esp
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
80483f9: 00
80483fa: b8 f0 84 04 08 mov $0x80484f0,%eax
80483ff: 8d 54 24 18 lea 0x18(%esp),%edx
8048403: 89 54 24 08 mov %edx,0x8(%esp)
8048407: 8d 54 24 1f lea 0x1f(%esp),%edx
804840b: 89 54 24 04 mov %edx,0x4(%esp)
804840f: 89 04 24 mov %eax,(%esp)
8048412: e8 e9 fe ff ff call 8048300 <printf@plt>
8048417: b8 00 00 00 00 mov $0x0,%eax
804841c: c9 leave
804841d: c3 ret
804841e: 90 nop
804841f: 90 nop
main段的反汇编奉上,不知道注意到
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
这两行没有,所以我才说它神奇
#10
标准并没有规定分配地址的顺序与变量声明的顺序一致。
080483e4 <main>:
80483e4: 55 push %ebp
80483e5: 89 e5 mov %esp,%ebp
80483e7: 83 e4 f0 and $0xfffffff0,%esp
80483ea: 83 ec 20 sub $0x20,%esp
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
80483f9: 00
80483fa: b8 f0 84 04 08 mov $0x80484f0,%eax
80483ff: 8d 54 24 18 lea 0x18(%esp),%edx
8048403: 89 54 24 08 mov %edx,0x8(%esp)
8048407: 8d 54 24 1f lea 0x1f(%esp),%edx
804840b: 89 54 24 04 mov %edx,0x4(%esp)
804840f: 89 04 24 mov %eax,(%esp)
8048412: e8 e9 fe ff ff call 8048300 <printf@plt>
8048417: b8 00 00 00 00 mov $0x0,%eax
804841c: c9 leave
804841d: c3 ret
804841e: 90 nop
804841f: 90 nop
main段的反汇编奉上,不知道注意到
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
这两行没有,所以我才说它神奇
所以我觉得扯蛋啊,之前用的工具都是按照默认顺序排的,最多给你来个字节对齐,这种玩法还没见过。环境是ubuntu12.04 lts gcc 4.6.3 虽然这个问题争论下去根本没意义,因为变量只要有空间能访问的到,存放顺序无所谓. 但不得不说挺扯蛋的.
#11
还是在验证MIPS非字节对齐访问问题的时候无意间用x86的编译器编错了发现的.
#12
扯完就轻松了,所以不按照规范写代码是很有隐患的。
标准并没有规定分配地址的顺序与变量声明的顺序一致。
080483e4 <main>:
80483e4: 55 push %ebp
80483e5: 89 e5 mov %esp,%ebp
80483e7: 83 e4 f0 and $0xfffffff0,%esp
80483ea: 83 ec 20 sub $0x20,%esp
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
80483f9: 00
80483fa: b8 f0 84 04 08 mov $0x80484f0,%eax
80483ff: 8d 54 24 18 lea 0x18(%esp),%edx
8048403: 89 54 24 08 mov %edx,0x8(%esp)
8048407: 8d 54 24 1f lea 0x1f(%esp),%edx
804840b: 89 54 24 04 mov %edx,0x4(%esp)
804840f: 89 04 24 mov %eax,(%esp)
8048412: e8 e9 fe ff ff call 8048300 <printf@plt>
8048417: b8 00 00 00 00 mov $0x0,%eax
804841c: c9 leave
804841d: c3 ret
804841e: 90 nop
804841f: 90 nop
main段的反汇编奉上,不知道注意到
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
这两行没有,所以我才说它神奇
所以我觉得扯蛋啊,之前用的工具都是按照默认顺序排的,最多给你来个字节对齐,这种玩法还没见过。环境是ubuntu12.04 lts gcc 4.6.3 虽然这个问题争论下去根本没意义,因为变量只要有空间能访问的到,存放顺序无所谓. 但不得不说挺扯蛋的.
#13
标准并没有规定分配地址的顺序与变量声明的顺序一致。
080483e4 <main>:
80483e4: 55 push %ebp
80483e5: 89 e5 mov %esp,%ebp
80483e7: 83 e4 f0 and $0xfffffff0,%esp
80483ea: 83 ec 20 sub $0x20,%esp
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
80483f9: 00
80483fa: b8 f0 84 04 08 mov $0x80484f0,%eax
80483ff: 8d 54 24 18 lea 0x18(%esp),%edx
8048403: 89 54 24 08 mov %edx,0x8(%esp)
8048407: 8d 54 24 1f lea 0x1f(%esp),%edx
804840b: 89 54 24 04 mov %edx,0x4(%esp)
804840f: 89 04 24 mov %eax,(%esp)
8048412: e8 e9 fe ff ff call 8048300 <printf@plt>
8048417: b8 00 00 00 00 mov $0x0,%eax
804841c: c9 leave
804841d: c3 ret
804841e: 90 nop
804841f: 90 nop
main段的反汇编奉上,不知道注意到
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
这两行没有,所以我才说它神奇
所以我觉得扯蛋啊,之前用的工具都是按照默认顺序排的,最多给你来个字节对齐,这种玩法还没见过。环境是ubuntu12.04 lts gcc 4.6.3 虽然这个问题争论下去根本没意义,因为变量只要有空间能访问的到,存放顺序无所谓. 但不得不说挺扯蛋的.
那是你没仔细看过,在x86系列机上一般编译器的编译结果都是让局部自动变量晚声明的地址更低,因为栈本身就是自上向下分配内存的。
#14
080483e4 <main>:
80483e4: 55 push %ebp
80483e5: 89 e5 mov %esp,%ebp
80483e7: 83 e4 f0 and $0xfffffff0,%esp
80483ea: 83 ec 20 sub $0x20,%esp
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
80483f9: 00
80483fa: b8 f0 84 04 08 mov $0x80484f0,%eax
80483ff: 8d 54 24 18 lea 0x18(%esp),%edx
8048403: 89 54 24 08 mov %edx,0x8(%esp)
8048407: 8d 54 24 1f lea 0x1f(%esp),%edx
804840b: 89 54 24 04 mov %edx,0x4(%esp)
804840f: 89 04 24 mov %eax,(%esp)
8048412: e8 e9 fe ff ff call 8048300 <printf@plt>
8048417: b8 00 00 00 00 mov $0x0,%eax
804841c: c9 leave
804841d: c3 ret
804841e: 90 nop
804841f: 90 nop
main段的反汇编奉上,不知道注意到
80483ed: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483f2: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
这两行没有,所以我才说它神奇
这两行有何神奇之处? 帮你把变量初始化为 0 了吗, 有什么大不了的呀?
你不觉得那2个地址差的太远了吗? 而且打印出的结果char 的地址比 int 的大
这也没什么好神奇的, 你如果去掉 printf 语句, 也就是不使用变量, 再去观察反汇编, 会发现变量的分配顺序和使用过变量的时候刚好相反. 这岂不是更神奇?