- 論壇徽章:
- 0
|
根據(jù)intel的volume3的7.2.4對任務(wù)寄存器的描述:
The STR (store task register) instruction stores the visible portion of the task register
in a general-purpose register or memory. This instruction can be executed by code
running at any privilege level in order to identify the currently running task. However,
it is normally used only by operating system software.
str指令在用戶態(tài)也可以使用,可是用戶態(tài)和內(nèi)核態(tài)讀取的結(jié)果不一樣,內(nèi)核態(tài)得到的結(jié)果與預(yù)期一致。
用戶態(tài)代碼如下:- #include <stdio.h>
- #define store_tr(tr) __asm__ ("str %0":"=mr" (tr))
- int main(void)
- {
- unsigned short tr = 0;
- store_tr(tr);
- printf("tr=0x%x\n", tr);
- return 0;
- }
復(fù)制代碼 結(jié)果為:tr=0x4000
內(nèi)核模塊代碼:- #include <linux/module.h>
- #include <linux/moduleparam.h>
- #include <linux/init.h>
- #include <linux/kernel.h> /* printk() */
- #define store_tr(tr) __asm__ ("str %0":"=mr" (tr))
- static int
- tr_module_init(void)
- {
- unsigned short tr = 0;
- printk(KERN_WARNING "tr_module_init\n");
- store_tr(tr);
- printk(KERN_WARNING "tr=0x%x\n", tr);
- return 0;
- }
- static void
- tr_module_exit(void)
- {
- printk(KERN_WARNING "tr_module_exit\n");
- }
- MODULE_AUTHOR("nobody");
- MODULE_LICENSE("Dual BSD/GPL");
- module_init(tr_module_init);
- module_exit(tr_module_exit);
復(fù)制代碼 結(jié)果為tr=0x80
我的環(huán)境是CENTOS5,內(nèi)核為2.6.18. 根據(jù)arch/i386/kernel/head.S中的全局段描述符的定義:- ENTRY(cpu_gdt_table)
- .quad 0x0000000000000000 /* NULL descriptor */
- .quad 0x0000000000000000 /* 0x0b reserved */
- .quad 0x0000000000000000 /* 0x13 reserved */
- .quad 0x0000000000000000 /* 0x1b reserved */
- .quad 0x0000000000000000 /* 0x20 unused */
- .quad 0x0000000000000000 /* 0x28 unused */
- .quad 0x0000000000000000 /* 0x33 TLS entry 1 */
- .quad 0x0000000000000000 /* 0x3b TLS entry 2 */
- .quad 0x0000000000000000 /* 0x43 TLS entry 3 */
- .quad 0x0000000000000000 /* 0x4b reserved */
- .quad 0x0000000000000000 /* 0x53 reserved */
- .quad 0x0000000000000000 /* 0x5b reserved */
- .quad 0x00cf9a000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
- .quad 0x00cf92000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
- .quad 0x00cffa000000ffff /* 0x73 user 4GB code at 0x00000000 */
- .quad 0x00cff2000000ffff /* 0x7b user 4GB data at 0x00000000 */
- .quad 0x0000000000000000 /* 0x80 TSS descriptor */
- .quad 0x0000000000000000 /* 0x88 LDT descriptor */
- /*
- * Segments used for calling PnP BIOS have byte granularity.
- * They code segments and data segments have fixed 64k limits,
- * the transfer segment sizes are set at run time.
- */
- .quad 0x00409a000000ffff /* 0x90 32-bit code */
- .quad 0x00009a000000ffff /* 0x98 16-bit code */
- .quad 0x000092000000ffff /* 0xa0 16-bit data */
- .quad 0x0000920000000000 /* 0xa8 16-bit data */
- .quad 0x0000920000000000 /* 0xb0 16-bit data */
- ...
復(fù)制代碼 TSS descriptor是第16個entry,每個entry是8bytes,所以tr中的段選擇子為16*8=128=0x80.
請教各位大牛為什么同樣的指令在用戶態(tài)得到的結(jié)果不對呢?
小弟為內(nèi)核菜鳥,請各位前輩多多賜教 |
|