在阅读于渊《一个操作系统的实现》时,遇到如下一个问题:
在代码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中被解释成了变量名,和我们上面所说的同一个意思。