【发布时间】:2016-10-11 10:24:38
【问题描述】:
我正在写一个迷你操作系统。当我写这段代码来显示时钟时,它出错了
7 void timer_callback(pt_regs *regs)
8 {
9 static uint32_t tick = 0;
10 printf("Tick: %dtimes\n", tick);
11 tick++;
12 }
tick 不是用 0 初始化,而是 1818389861。但是如果用 0x01 或其他任何零来初始化,就可以了!!!
所以我写了一个简单的 c 文件然后 objdump:
staic.o: file format elf32-i386
Disassembly of section .text:
00000000 <main>:
extern void printf(char *, int);
int main(){
0: 8d 4c 24 04 lea 0x4(%esp),%ecx
4: 83 e4 f0 and $0xfffffff0,%esp
7: ff 71 fc pushl -0x4(%ecx)
a: 55 push %ebp
b: 89 e5 mov %esp,%ebp
d: 51 push %ecx
e: 83 ec 04 sub $0x4,%esp
static int a = 1;
printf("%d\n", a);
11: a1 00 00 00 00 mov 0x0,%eax
16: 83 ec 08 sub $0x8,%esp
19: 50 push %eax
1a: 68 00 00 00 00 push $0x0
1f: e8 fc ff ff ff call 20 <main+0x20>
24: 83 c4 10 add $0x10,%esp
return 0;
27: b8 00 00 00 00 mov $0x0,%eax
}
2c: 8b 4d fc mov -0x4(%ebp),%ecx
2f: c9 leave
30: 8d 61 fc lea -0x4(%ecx),%esp
33: c3 ret
好奇怪,没用过内存!!!
更新:让我说清楚
第二个 static.c 是一个实验,它被认为显示没有使用内存,但我错了,
mov 0x0 %eab是。我混淆了 0x0 和 $0x0 /..\我的起源问题是为什么 tick 不能成功初始化为 0。(但可以初始化为 1 或任何其他数字)。
我用gdb再次查找,好吧,它确实像
mov一样使用内存,但真正强大的是内存
eax,ds:0x106010x 0x106010不是0,但应该是,正如我所说,如果我让tick = 1 or anythingelse,内存按照我的意愿进行初始化,那就太奇怪了!-
工具:gdb ,objdump 返回不同的asm(不同的手段,不是formate),因为,刚学os,不擅长c,所以就放了,忽略....
【问题讨论】:
-
这里的问题是什么?您还显示了一些 C 代码,但反汇编是针对不同的东西 - 连接是什么?你指的那个奇怪的程序集在哪里?
-
如果第一次调用 timer_callback 时滴答声没有打印为零,那么您的代码中的其他地方一定有未定义的行为。在您的第二个示例中,
a没有使用内存,因为编译器已经对其进行了优化,它不需要是静态的,因为您只打印一次然后退出。 -
11: 处的指令是从地址 0x0 到 %eax 的 mov。地址为 0x0 的原因是因为这是一个目标文件,并且链接器所做的重定位尚未完成。链接后,这将是来自存储
a的正确内存位置的正确地址。 -
@Secto Kia 不管我给它起什么名字,仍然不是零。你的意思是什么“未定义的行为”?
-
大部分代码。您必须有一些其他错误的代码导致未定义的行为。一个程序只会让你的 timer_callback 函数工作并打印“0times”。您可能不使用 timer_callback。如果您在其他地方有错误,您可能会在不知不觉中写到内存已用刻度的顶部。