x86組合語言 從真實模式到保護模式 疑問彙總
該段長度是4K,ESP初始值為0000 0000, 0xFFFFFFFF-0xFFFFEFFF = 4KB
實際使用的段界限是0xFFFFE * 0x1000+0xFFF=0xFFFFEFFF
從而得到0xFFFFE
;建立0特權級堆疊
mov ecx,4096
mov eax,ecx ;為生成堆疊高階地址做準備
mov [es:esi+0x1a],ecx
shr dword [es:esi+0x1a],12 ;登記0特權級堆疊尺寸到TCB
call sys_routine_seg_sel:allocate_memory
add eax,ecx ;堆疊必須使用高階地址為基地址
mov [es:esi+0x1e],eax ;登記0特權級堆疊基地址到TCB
[color=red][b] mov ebx,0xffffe ;段長度(界限)[/b][/color]
mov ecx,0x00c09600 ;4KB粒度,讀寫,特權級0
call sys_routine_seg_sel:make_seg_descriptor
mov ebx,esi ;TCB的基地址
call fill_descriptor_in_ldt
;or cx,0000_0000_0000_0000 ;設定選擇子的特權級為0
mov [es:esi+0x22],cx ;登記0特權級堆疊選擇子到TCB
mov dword [es:esi+0x24],0 ;登記0特權級堆疊初始ESP到TCB
---------------
iret/iretd 怎麼會自動切換到程式管理器任務上邊去呢? 這個中間的處理邏輯是怎麼的。。這個過程是處理器固化處理嗎? ----找到當前的TSS的頭部的前一個任務的TSS指標(即程式管理器任務)更新相關的暫存器資料切換過去的
書中只有一句話,在295 的中間, “第374行,通過iretd指令轉換到前一個任務”
這個應該是我表述有問題吧。。。 我現在的理解 :檢查NT位,如果為1,找到當前的TSS的頭部的前一個任務的TSS指標(即程式管理器任務)更新相關的暫存器資料切換過去的
NT為1,表示是巢狀任務返回,當前TSS中的連結欄位儲存前一任務的TSS的選擇子,取出該選擇子,進行任務切換完成返回。
如是NT為0,表示當前任務內返回, 從stack彈出返回指標EIP及CS,然後彈出EFLAG值。 彈出CS中RPL,確定返回後的特權級。接下來與RET類似。
In Protected Mode, the action of the IRET instruction depends on the settings of the NT (nested task) and VM flags in the EFLAGS register and the VM flag in the EFLAGS image stored on the current stack. Depending on the setting of these flags, the processor performs the following types of interrupt returns:
• Return from virtual-8086 mode.
• Return to virtual-8086 mode.
• Intra-privilege level return.
• Inter-privilege level return.
• Return from nested task (task switch).
[color=blue]If the NT flag (EFLAGS register) is cleared, the IRET instruction performs a far return from the interrupt procedure, without a task switch.[/color] The code segment being returned to must be equally or less privileged than the interrupt handler routine (as indicated by the RPL field of the code segment selector popped from the stack).
As with a real-address mode interrupt return, the IRET instruction pops the return instruction pointer, return code segment selector, and EFLAGS image from the stack to the EIP, CS, and EFLAGS registers, respectively, and then resumes execution of the interrupted program or procedure. If the return is to another privilege level, the IRET instruction also pops the stack pointer and SS from the stack, before resuming program execution. If the return is to virtual-8086 mode, the processor also pops the
data segment registers from the stack.
[color=blue]If the NT flag is set, the IRET instruction performs a task switch (return) from a nested task (a task called with a CALL instruction, an interrupt, or an exception) back to the calling or interrupted task.[/color] The updated state of the task executing the IRET
instruction is saved in its TSS. If the task is re-entered later, the code that follows the IRET instruction is executed.
If the NT flag is set and the processor is in IA-32e mode, the IRET instruction causes a general protection exception.
In 64-bit mode, the instruction’s default operation size is 32 bits. Use of the REX.W prefix promotes operation to 64 bits (IRETQ). See the summary chart at the beginning of this section for encoding data and limits.
--------以下是請教關東鼠俠QQ交流記錄-----------------------------------------
你先回到前面p210
【團長】關東鼠 2017/3/20 星期一 09:58:40
看看書上那幾頁。
【連長】^魚小雄^ 2017/3/20 星期一 09:59:14
好的
10:00:52
【團長】關東鼠 2017/3/20 星期一 10:00:52
p.214
10:05:24
【團長】關東鼠 2017/3/20 星期一 10:05:24
整明白沒有?
【連長】^魚小雄^ 2017/3/20 星期一 10:05:36
還沒有。。
【連長】^魚小雄^ 2017/3/20 星期一 10:05:43
有點笨啊。。
【團長】關東鼠 2017/3/20 星期一 10:06:08
不是笨,是棧的界限這一塊確實很繞很燒腦。
【連長】^魚小雄^ 2017/3/20 星期一 10:06:15
描述符中的段界限值*0x1000+0xFFF
【團長】關東鼠 2017/3/20 星期一 10:06:42
我來問你,我們給ESP暫存器的初值是多少?
【連長】^魚小雄^ 2017/3/20 星期一 10:06:50
從14章這個程式碼裡看,他的長度4K
【連長】^魚小雄^ 2017/3/20 星期一 10:06:52
0
【連長】^魚小雄^ 2017/3/20 星期一 10:07:19
ESP 中的初值應該是0
10:07:35
【團長】關東鼠 2017/3/20 星期一 10:07:35
好,壓棧時,是先減ESP。如果運算元是2個位元組,那麼,壓棧時,ESP的新值是多少?
【連長】^魚小雄^ 2017/3/20 星期一 10:08:16
FFFFE
【連長】^魚小雄^ 2017/3/20 星期一 10:08:21
FFFE
【團長】關東鼠 2017/3/20 星期一 10:09:01
糊塗了吧?ESP是32位的暫存器。
【連長】^魚小雄^ 2017/3/20 星期一 10:09:07
是的。。
【連長】^魚小雄^ 2017/3/20 星期一 10:09:12
FFFF FFFE
10:09:36
【團長】關東鼠 2017/3/20 星期一 10:09:36
所以,每次壓棧時,ESP的值必須在棧界限值以內。
【團長】關東鼠 2017/3/20 星期一 10:10:48
對於棧來說,實際使用的段界限,是不允許訪問的最低端地址。
10:11:38
【連長】^魚小雄^ 2017/3/20 星期一 10:11:38
恩,對的。。
【連長】^魚小雄^ 2017/3/20 星期一 10:11:46
所以是用0 - 4k
【團長】關東鼠 2017/3/20 星期一 10:12:44
所以,我們這裡是界限值0xFFFFE
所以,在這裡,實際使用的段界限是0xFFFFE * 0x1000+0xFFFF=0xFFFFEFFF
【團長】關東鼠 2017/3/20 星期一 10:12:58
或者說,ESP必須大小0xFFFFEFFF
【團長】關東鼠 2017/3/20 星期一 10:13:03
大於
【團長】關東鼠 2017/3/20 星期一 10:13:21
0xFFFFFFFF-0xFFFFEFFF = 4KB
【連長】^魚小雄^ 2017/3/20 星期一 10:13:36
恩,是的,終於搞明白了
【連長】^魚小雄^ 2017/3/20 星期一 10:13:55
這個要備註下
【團長】關東鼠 2017/3/20 星期一 10:14:15
再版的時候,朕也改一下,說得更清楚些。
【團長】linux-果 2017/3/20 星期一 10:14:19
155.94.235.113這開啟速度還可以吧
【團長】linux-果 2017/3/20 星期一 10:14:23
155.94.235.113
10:19:08
【團長】關東鼠 2017/3/20 星期一 10:19:08
@^魚小雄^ 你可以將這個問題寫成一個部落格,朕率文武百官前去拜讀。
【連長】^魚小雄^ 2017/3/20 星期一 10:19:25
哈哈,好的。。。