在x86汇编中使用C语言的全局变量

时间:2021-10-20 12:09:44

在阅读于渊《一个操作系统的实现》时,遇到如下一个问题:

在代码chapter6/r/kernel/kernel.asm中,有这样一段汇编代码:

357 restart:
358 mov esp, [p_proc_ready]
359 lldt [esp + P_LDT_SEL]
360 lea eax, [esp + P_STACKTOP]
361 mov dword [tss + TSS3_S_SP0], eax
362 restart_reenter:
363 dec dword [k_reenter]
364 pop gs
365 pop fs
366 pop es
367 pop ds
368 popad
369 add esp, 4
370 iretd
第358行的代码一开始让我疑惑,因为这句话的目的是赋值给esp一个地址值, p_proc_ready是一个结构体指针,照理说是不应该加方括号的,因为方括号表示p_proc_ready这个地址值所指向的内存单元的内容。

p_proc_ready是这样定义的:

EXTERN PROCESS* p_proc_ready;
PROCESS是struct类型的一个结构体。

后来想明白了,p_proc_ready在C语言和x86汇编中代表着不同的含义,在C中它代表一个指向结构体的指针,而在汇编中,它代表的是一段连续内存空间的别名,就像357行的restart。事实上,C中所有的变量名在汇编看来都是标签,都是一段连续内存空间的别名。

这样358行就好理解了,p_proc_ready这个地址标签所指向的内容就是我们需要的指针值。

在下面这篇博客中,介绍了相反的应用,在C中使用汇编定义的全局变量,结果是汇编中的地址标签在C中被解释成了变量名,和我们上面所说的同一个意思。

C语言中通过全局变量引用汇编语言中的全局标签