學(xué)習(xí)筆記
《x86匯編語言:從實(shí)模式到保護(hù)模式》
http://www.reibang.com/p/d481cb547e9f
第十三章的 代碼
- 用戶程序
c13.asm
代碼行數(shù)81行 - 內(nèi)核程序
c13_core.asm
代碼行數(shù)601行 - 加載程序
c13_mbr.asm
代碼行數(shù)221行
加載程序 c13_mbr.asm
調(diào)用過程
- 1、內(nèi)核程序 分配內(nèi)存
- 2、內(nèi)核程序 讀取、加載用戶程序
- 3浇雹、內(nèi)核程序 轉(zhuǎn)移CPU控制權(quán)給用戶程序
- 4、用戶程序 執(zhí)行
- 5已球、用戶程序 返回到 內(nèi)核程序
- 6韧掩、內(nèi)核程序 執(zhí)行象浑,最終進(jìn)入停機(jī)狀態(tài)
內(nèi)存布局示意圖
運(yùn)行結(jié)果
代碼使用
配書工具 :
編譯工具nasmide.exe
寫扇區(qū)工具fixvhdwr.exe
- 1、編譯加載程序
c13_mbr.asm
句携,生成二進(jìn)制文件c13_mbr.bin
榔幸,將c13_mbr.bin
文件寫入虛擬硬盤的LBA邏輯扇區(qū)0號(hào); - 2、編譯內(nèi)核程序
c13_core.asm
削咆,生成二進(jìn)制文件c13_core.bin
牍疏,將c13_core.bin
文件寫入虛擬硬盤的LBA邏輯扇區(qū)1號(hào); - 3拨齐、編譯用戶程序
c13.asm
鳞陨,生成二進(jìn)制文件c13.bin
,將c13.bin
文件寫入虛擬硬盤的LBA邏輯扇區(qū)50號(hào)瞻惋; - 4厦滤、將數(shù)據(jù)文件
diskdata.txt
寫入虛擬硬盤LBA邏輯扇區(qū)100號(hào);
完整源碼(用戶程序歼狼,增加注釋)
;代碼清單13-3
;文件名:code_13.asm
;文件說明:用戶程序
;創(chuàng)建日期:18:23 2018/6/3
;===========================================================
SECTION header vstart=0
program_length dd program_end ;程序總長(zhǎng)度#0x00
head_len dd header_end ;程序頭部的長(zhǎng)度#0x04
stack_seg dd 0 ;用于接收堆棧段選擇子#0x08
stack_len dd 1 ;程序建議的堆棧大小#0xc
prgentry dd start ;程序入口地址#0x10
code_seg dd section.code.start ;代碼段位置#0x14
code_len dd code_end ;代碼段長(zhǎng)度#0x18
data_seg dd section.data.start ;數(shù)據(jù)段位置#0x1c
data_len dd data_end ;數(shù)據(jù)段長(zhǎng)度#0x20
;------------------------------------------------------------
;符號(hào)地址檢索表
salt_items dd (header_end - salt)/256 ;#0x24
salt:
PrintString db '@PrintString'
times 256-($-PrintString) db 0
TerminateProgram db '@TerminateProgram'
times 256-($-TerminateProgram) db 0
ReadDiskData db '@ReadDiskData'
times 256-($-ReadDiskData) db 0
header_end:
;===========================================================
SECTION data vstart=0
buffer times 1024 db 0 ;緩沖區(qū)
message_1 db 0x0d,0x0a,0x0d,0x0a
db '**********User program is runing**********'
db 0x0d,0x0a,0
message_2 db 'Disk data:',0x0d,0x0a,0
data_end:
;===========================================================
[bits 32]
;===========================================================
SECTION code vstart=0
start:
mov eax,ds ;ds此時(shí)指向用戶程序頭部段
mov fs,eax
mov eax,[stack_seg]
mov ss,eax
mov esp,0
mov eax,[data_seg]
mov ds,eax
mov ebx,message_1
call far [fs:PrintString]
mov eax,100 ;源地址:數(shù)據(jù)文件放在硬盤LBA邏輯扇區(qū)號(hào)100處
mov ebx,buffer ;目的地址:緩沖區(qū)偏移地址
call far [fs:ReadDiskData] ;段間調(diào)用:讀扇區(qū)
mov ebx,message_2
call far [fs:PrintString]
mov ebx,buffer
call far [fs:PrintString]
jmp far [fs:TerminateProgram] ;將CPU控制權(quán)返回到內(nèi)核程序
code_end:
;===========================================================
SECTION trail
;-----------------------------------------------------------
program_end:
代碼說明
4-3 將描述符的選擇子回寫到用戶程序頭部段
6 重定位用戶程序的SALT表
當(dāng)CPU轉(zhuǎn)到用戶程序代碼段開始執(zhí)行時(shí)掏导,DS寄存器指向的是用戶程序頭部段
這是由于 內(nèi)核程序 調(diào)用 load_relocate_program 的最后
會(huì)傳遞一個(gè)返回參數(shù)到寄存器AX mov ax,[es:0x04]
此時(shí)的 [es:0x04]指向的正是 用戶程序的head_len 標(biāo)號(hào)處
在經(jīng)歷過 步驟 4-3 的段選擇子回寫之后,這個(gè)標(biāo)號(hào)現(xiàn)在存的就是 指向用戶程序頭部段的段選擇子
借由AX寄存器做一個(gè)返回參數(shù)
之后羽峰,內(nèi)核程序又通過 mov ds,ax 將這個(gè)值傳遞給ds
緊隨其后的是 一條跳轉(zhuǎn)指令 轉(zhuǎn)移CPU控制權(quán)給 用戶程序
mov ds,ax
jmp far [0x10]
因此趟咆,在用戶程序真正開始執(zhí)行的時(shí)候,DS寄存器 恰恰指向用戶程序的頭部段梅屉。