ubuntu gcc 4.6.3一个神奇的问题

时间:2022-12-24 09:13:57
这段代码"老"神奇了:

#include<stdio.h>

int main()
{
    char a;
    int  b;
    printf("%x\n%x\n", &a, &b);
    return 0;
}

编译(x86)会有警告,不过没关系,不过打出来的地址就得把你吓一跳了。 ubuntu gcc 4.6.3一个神奇的问题

14 个解决方案

#1


用法有问题,没什么神奇的,打印地址用%p:
printf("%p\n%p\n", &a, &b);

引用 楼主 nadleeh123 的回复:
这段代码"老"神奇了:

#include<stdio.h>

int main()
{
    char a;
    int  b;
    printf("%x\n%x\n", &a, &b);
    return 0;
}

编译(x86)会有警告,不过没关系,不过打出来的地址就得把你吓一跳了。 ubuntu gcc 4.6.3一个神奇的问题

#2


LZ想表达什么?打出的地址是什么?

#3


引用 1 楼 turingo 的回复:
用法有问题,没什么神奇的,打印地址用%p:
printf("%p\n%p\n", &a, &b);

Quote: 引用 楼主 nadleeh123 的回复:

这段代码"老"神奇了:

#include<stdio.h>

int main()
{
    char a;
    int  b;
    printf("%x\n%x\n", &a, &b);
    return 0;
}

编译(x86)会有警告,不过没关系,不过打出来的地址就得把你吓一跳了。 ubuntu gcc 4.6.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)
这两行没有,所以我才说它神奇 ubuntu gcc 4.6.3一个神奇的问题

#5


VC 的 Debug 版本也经常会在变量中间插入很多的 0xcc 空隙, 用来检查你对变量的写入是否有越界.

#6


引用 4 楼 nadleeh123 的回复:

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)
这两行没有,所以我才说它神奇 ubuntu gcc 4.6.3一个神奇的问题


这两行有何神奇之处? 帮你把变量初始化为 0 了吗, 有什么大不了的呀?

#7


引用 5 楼 adlay 的回复:
VC 的 Debug 版本也经常会在变量中间插入很多的 0xcc 空隙, 用来检查你对变量的写入是否有越界.


我的是gcc -。- VC神马的别乱入 ubuntu gcc 4.6.3一个神奇的问题

#8


引用 6 楼 adlay 的回复:
Quote: 引用 4 楼 nadleeh123 的回复:


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)
这两行没有,所以我才说它神奇 ubuntu gcc 4.6.3一个神奇的问题


这两行有何神奇之处? 帮你把变量初始化为 0 了吗, 有什么大不了的呀?

你不觉得那2个地址差的太远了吗? 而且打印出的结果char 的地址比 int 的大

#9


标准并没有规定分配地址的顺序与变量声明的顺序一致。

引用 4 楼 nadleeh123 的回复:

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)
这两行没有,所以我才说它神奇 ubuntu gcc 4.6.3一个神奇的问题

#10


引用 9 楼 turingo 的回复:
标准并没有规定分配地址的顺序与变量声明的顺序一致。

Quote: 引用 4 楼 nadleeh123 的回复:


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)
这两行没有,所以我才说它神奇 ubuntu gcc 4.6.3一个神奇的问题

所以我觉得扯蛋啊,之前用的工具都是按照默认顺序排的,最多给你来个字节对齐,这种玩法还没见过。环境是ubuntu12.04 lts gcc 4.6.3 虽然这个问题争论下去根本没意义,因为变量只要有空间能访问的到,存放顺序无所谓. 但不得不说挺扯蛋的.

#11


还是在验证MIPS非字节对齐访问问题的时候无意间用x86的编译器编错了发现的.

#12


扯完就轻松了,所以不按照规范写代码是很有隐患的。

引用 10 楼 nadleeh123 的回复:
Quote: 引用 9 楼 turingo 的回复:

标准并没有规定分配地址的顺序与变量声明的顺序一致。

Quote: 引用 4 楼 nadleeh123 的回复:


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)
这两行没有,所以我才说它神奇 ubuntu gcc 4.6.3一个神奇的问题

所以我觉得扯蛋啊,之前用的工具都是按照默认顺序排的,最多给你来个字节对齐,这种玩法还没见过。环境是ubuntu12.04 lts gcc 4.6.3 虽然这个问题争论下去根本没意义,因为变量只要有空间能访问的到,存放顺序无所谓. 但不得不说挺扯蛋的.

#13


引用 10 楼 nadleeh123 的回复:
Quote: 引用 9 楼 turingo 的回复:

标准并没有规定分配地址的顺序与变量声明的顺序一致。

Quote: 引用 4 楼 nadleeh123 的回复:


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)
这两行没有,所以我才说它神奇 ubuntu gcc 4.6.3一个神奇的问题

所以我觉得扯蛋啊,之前用的工具都是按照默认顺序排的,最多给你来个字节对齐,这种玩法还没见过。环境是ubuntu12.04 lts gcc 4.6.3 虽然这个问题争论下去根本没意义,因为变量只要有空间能访问的到,存放顺序无所谓. 但不得不说挺扯蛋的.


那是你没仔细看过,在x86系列机上一般编译器的编译结果都是让局部自动变量晚声明的地址更低,因为栈本身就是自上向下分配内存的。

#14


引用 8 楼 nadleeh123 的回复:
Quote: 引用 6 楼 adlay 的回复:

Quote: 引用 4 楼 nadleeh123 的回复:


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)
这两行没有,所以我才说它神奇 ubuntu gcc 4.6.3一个神奇的问题


这两行有何神奇之处? 帮你把变量初始化为 0 了吗, 有什么大不了的呀?

你不觉得那2个地址差的太远了吗? 而且打印出的结果char 的地址比 int 的大


这也没什么好神奇的, 你如果去掉 printf 语句, 也就是不使用变量, 再去观察反汇编, 会发现变量的分配顺序和使用过变量的时候刚好相反. 这岂不是更神奇?

#1


用法有问题,没什么神奇的,打印地址用%p:
printf("%p\n%p\n", &a, &b);

引用 楼主 nadleeh123 的回复:
这段代码"老"神奇了:

#include<stdio.h>

int main()
{
    char a;
    int  b;
    printf("%x\n%x\n", &a, &b);
    return 0;
}

编译(x86)会有警告,不过没关系,不过打出来的地址就得把你吓一跳了。 ubuntu gcc 4.6.3一个神奇的问题

#2


LZ想表达什么?打出的地址是什么?

#3


引用 1 楼 turingo 的回复:
用法有问题,没什么神奇的,打印地址用%p:
printf("%p\n%p\n", &a, &b);

Quote: 引用 楼主 nadleeh123 的回复:

这段代码"老"神奇了:

#include<stdio.h>

int main()
{
    char a;
    int  b;
    printf("%x\n%x\n", &a, &b);
    return 0;
}

编译(x86)会有警告,不过没关系,不过打出来的地址就得把你吓一跳了。 ubuntu gcc 4.6.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)
这两行没有,所以我才说它神奇 ubuntu gcc 4.6.3一个神奇的问题

#5


VC 的 Debug 版本也经常会在变量中间插入很多的 0xcc 空隙, 用来检查你对变量的写入是否有越界.

#6


引用 4 楼 nadleeh123 的回复:

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)
这两行没有,所以我才说它神奇 ubuntu gcc 4.6.3一个神奇的问题


这两行有何神奇之处? 帮你把变量初始化为 0 了吗, 有什么大不了的呀?

#7


引用 5 楼 adlay 的回复:
VC 的 Debug 版本也经常会在变量中间插入很多的 0xcc 空隙, 用来检查你对变量的写入是否有越界.


我的是gcc -。- VC神马的别乱入 ubuntu gcc 4.6.3一个神奇的问题

#8


引用 6 楼 adlay 的回复:
Quote: 引用 4 楼 nadleeh123 的回复:


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)
这两行没有,所以我才说它神奇 ubuntu gcc 4.6.3一个神奇的问题


这两行有何神奇之处? 帮你把变量初始化为 0 了吗, 有什么大不了的呀?

你不觉得那2个地址差的太远了吗? 而且打印出的结果char 的地址比 int 的大

#9


标准并没有规定分配地址的顺序与变量声明的顺序一致。

引用 4 楼 nadleeh123 的回复:

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)
这两行没有,所以我才说它神奇 ubuntu gcc 4.6.3一个神奇的问题

#10


引用 9 楼 turingo 的回复:
标准并没有规定分配地址的顺序与变量声明的顺序一致。

Quote: 引用 4 楼 nadleeh123 的回复:


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)
这两行没有,所以我才说它神奇 ubuntu gcc 4.6.3一个神奇的问题

所以我觉得扯蛋啊,之前用的工具都是按照默认顺序排的,最多给你来个字节对齐,这种玩法还没见过。环境是ubuntu12.04 lts gcc 4.6.3 虽然这个问题争论下去根本没意义,因为变量只要有空间能访问的到,存放顺序无所谓. 但不得不说挺扯蛋的.

#11


还是在验证MIPS非字节对齐访问问题的时候无意间用x86的编译器编错了发现的.

#12


扯完就轻松了,所以不按照规范写代码是很有隐患的。

引用 10 楼 nadleeh123 的回复:
Quote: 引用 9 楼 turingo 的回复:

标准并没有规定分配地址的顺序与变量声明的顺序一致。

Quote: 引用 4 楼 nadleeh123 的回复:


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)
这两行没有,所以我才说它神奇 ubuntu gcc 4.6.3一个神奇的问题

所以我觉得扯蛋啊,之前用的工具都是按照默认顺序排的,最多给你来个字节对齐,这种玩法还没见过。环境是ubuntu12.04 lts gcc 4.6.3 虽然这个问题争论下去根本没意义,因为变量只要有空间能访问的到,存放顺序无所谓. 但不得不说挺扯蛋的.

#13


引用 10 楼 nadleeh123 的回复:
Quote: 引用 9 楼 turingo 的回复:

标准并没有规定分配地址的顺序与变量声明的顺序一致。

Quote: 引用 4 楼 nadleeh123 的回复:


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)
这两行没有,所以我才说它神奇 ubuntu gcc 4.6.3一个神奇的问题

所以我觉得扯蛋啊,之前用的工具都是按照默认顺序排的,最多给你来个字节对齐,这种玩法还没见过。环境是ubuntu12.04 lts gcc 4.6.3 虽然这个问题争论下去根本没意义,因为变量只要有空间能访问的到,存放顺序无所谓. 但不得不说挺扯蛋的.


那是你没仔细看过,在x86系列机上一般编译器的编译结果都是让局部自动变量晚声明的地址更低,因为栈本身就是自上向下分配内存的。

#14


引用 8 楼 nadleeh123 的回复:
Quote: 引用 6 楼 adlay 的回复:

Quote: 引用 4 楼 nadleeh123 的回复:


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)
这两行没有,所以我才说它神奇 ubuntu gcc 4.6.3一个神奇的问题


这两行有何神奇之处? 帮你把变量初始化为 0 了吗, 有什么大不了的呀?

你不觉得那2个地址差的太远了吗? 而且打印出的结果char 的地址比 int 的大


这也没什么好神奇的, 你如果去掉 printf 语句, 也就是不使用变量, 再去观察反汇编, 会发现变量的分配顺序和使用过变量的时候刚好相反. 这岂不是更神奇?