10.5 Initialization Example
初始化的例子

译注:本来想把这个例子全部注释完,但由于对intel汇编实不熟悉,有太多的伪指令,本人也是免强看懂,所以就不再做翻译了。

$TITLE ('Initial Task')        #此处title为开始标识,$符号表示取地址
NAME INIT #为一段程序命名
init_stack SEGMENT RW #定义栈段 可读写 标识符为init_stack
DW DUP(?) #保留20个双字位置
tos LABEL WORD #定义一个标号tos,类型为字
init_stack ENDS #栈段init_stack定义结束
init_data SEGMENT RW PUBLIC #定义数据段 公共 可读写 标识符为init_data
DW DUP(?) #段长度20个双字,即重复保留20个双字
init_data ENDS #数据段定义结束
init_code SEGMENT ER PUBLIC #代码段开始 可执行,只读,公共
ASSUME DS:init_data #设定此时的数据段为上面定义的数据段
nop
nop
nop
init_start: #入口点标识符
; set up stack
mov ax, init_stack #设置栈,将标识符init_stack放入ax
mov ss, ax #设置栈段寄存器
mov esp, offset tos #设置栈顶指针为tos的偏移,栈是高向低
mov a1, #al中放1
blink: #标号blink
xor a1, #al清0
out 0e4h,a1 #向0e4H端口输入al中值,此时al =
mov cx,3FFFh #cx = 3FFFh
here: #标号here
dec cx #cx = cx -
jnz here #ZF位不等0, 则跳转到here标号处
jmp SHORT blink #跳到blink标号处
Hlt #停机
init_code ends #代码段结束
END init_start, SS:init_stack, DS:init_data #入口点结束 $TITLE('Protected Mode Transition -- 386 initialization')
NAME RESET
;*****************************************************************
; Upon reset the 386 starts executing at address 0FFFFFFF0H. The
; upper 12 address bits remain high until a FAR call or jump is
; executed.
;
; Assume the following:
;
;
; - a short jump at address 0FFFFFFF0H (placed there by the
; system builder) causes execution to begin at START in segment
; RESET_CODE.
;
;
; - segment RESET_CODE is based at physical address 0FFFF0000H,
; i.e. at the start of the last 64K in the 4G address space.
; Note that this is the base of the CS register at reset. If
; you locate ROM code above this address, you will need to
; figure out an adjustment factor to address things within this
; segment.
;
;*****************************************************************
$EJECT ;
; Define addresses to locate GDT and IDT in RAM.
; These addresses are also used in the BLD386 file that defines
; the GDT and IDT. If you change these addresses, make sure you
; change the base addresses specified in the build file.
GDTbase EQU 00001000H ; physical address for GDT base
IDTbase EQU 00000400H ; physical address for IDT base
PUBLIC GDT_EPROM
PUBLIC IDT_EPROM
PUBLIC START
DUMMY segment rw ; ONLY for ASM386 main module stack init
DW
DUMMY ends
;*****************************************************************
;
; Note: RESET CODE must be USEl6 because the 386 initally executes
; in real mode.
;
RESET_CODE segment er PUBLIC USE16
ASSUME DS:nothing, ES:nothing
;
; 386 Descriptor template
DESC STRUC
lim_0_15 DW ; limit bits (0..15)
bas_0_15 DW ; base bits (0..15)
bas_16_23 DB ; base bits (16..23)
access DB ; access byte
gran DB ; granularity byte
bas_24_31 DB ; base bits (24..31)
DESC ENDS
; The following is the layout of the real GDT created by BLD386.
; It is located in EPROM and will be copied to RAM.
;
; GDT[O] ... NULL
; GDT[1] ... Alias for RAM GDT
; GDT[2] ... Alias for RAM IDT
; GDT[2] ... initial task TSS
; GDT[3] ... initial task TSS alias
; GDT[4] ... initial task LDT
; GDT[5] ... initial task LDT alias
;
; define entries in GDT and IDT.
GDT_ENTRIES EQU
IDT_ENTRIES EQU
; define some constants to index into the real GDT
GDT_ALIAS EQU *SIZE DESC
IDT_ALIAS EQU *SIZE DESC
INIT_TSS EQU *SIZE DESC
INIT_TSS_A EQU *SIZE DESC
INIT_LDT EQU *SIZE DESC
INIT_LDT_A EQU *SIZE DESC
;
; location of alias in INIT_LDT
INIT_LDT_ALIAS EQU *SIZE DESC
;
; access rights byte for DATA and TSS descriptors
DS_ACCESS EQU 010010010B
TSS_ACCESS EQU 010001001B
;
; This temporary GDT will be used to set up the real GDT in RAM.
Temp_GDT LABEL BYTE ; tag for begin of scratch GDT
NULL_DES DESC <> ; NULL descriptor
; 32-Gigabyte data segment based at 0
FLAT_DES DESC <0FFFFH,,,92h,0CFh,>
GDT_eprom DP ? ; Builder places GDT address and limit
; in this 6 byte area.
IDT_eprom DP ? ; Builder places IDT address and limit
; in this 6 byte area.
;
; Prepare operand for loadings GDTR and LDTR.
TGDT_pword LABEL PWORD ; for temp GDT
DW end_Temp_GDT_Temp_GDT -
DD
GDT_pword LABEL PWORD ; for GDT in RAM
DW GDT_ENTRIES * SIZE DESC -
DD GDTbase
IDT_pword LABEL PWORD ; for IDT in RAM
DW IDT_ENTRIES * SIZE DESC -
DD IDTbase
end_Temp_GDT LABEL BYTE
;
; Define equates for addressing convenience.
GDT_DES_FLAT EQU DS:GDT_ALIAS +GDTbase
IDT_DES_FLAT EQU DS:IDT_ALIAS +GDTbase
INIT_TSS_A_OFFSET EQU DS:INIT_TSS_A
INIT_TSS_OFFSET EQU DS:INIT_TSS
INIT_LDT_A_OFFSET EQU DS:INIT_LDT_A
INIT_LDT_OFFSET EQU DS:INIT_LDT
; define pointer for first task switch
ENTRY POINTER LABEL DWORD
DW , INIT_TSS
;******************************************************************
;
; Jump from reset vector to here.
START:
CLI ;disable interrupts
CLD ;clear direction flag
LIDT NULL_des ;force shutdown on errors
;
; move scratch GDT to RAM at physical 0
XOR DI,DI
MOV ES,DI ;point ES:DI to physical location 0
MOV SI,OFFSET Temp_GDT
MOV CX,end_Temp_GDT-Temp_GDT ;set byte count
INC CX
;
; move table
REP MOVS BYTE PTR ES:[DI],BYTE PTR CS:[SI]
LGDT tGDT_pword ;load GDTR for Temp. GDT
;(located at 0)
; switch to protected mode
MOV EAX,CR0 ;get current CRO
MOV EAX, ;set PE bit
MOV CRO,EAX ;begin protected mode
;
; clear prefetch queue
JMP SHORT flush
flush:
; set DS,ES,SS to address flat linear space (0 ... 4GB)
MOV BX,FLAT_DES-Temp_GDT
MOV US,BX
MOV ES,BX
MOV SS,BX
;
; initialize stack pointer to some (arbitrary) RAM location
MOV ESP, OFFSET end_Temp_GDT
;
; copy eprom GDT to RAM
MOV ESI,DWORD PTR GDT_eprom + ; get base of eprom GDT
; (put here by builder).
MOV EDI,GDTbase ; point ES:EDI to GDT base in RAM.
MOV CX,WORD PTR gdt_eprom + ; limit of eprom GDT
INC CX
SHR CX, ; easier to move words
CLD
REP MOVS WORD PTR ES:[EDI],WORD PTR DS:[ESI]
;
; copy eprom IDT to RAM
;
MOV ESI,DWORD PTR IDT_eprom + ; get base of eprom IDT
; (put here by builder)
MOV EDI,IDTbase ; point ES:EDI to IDT base in RAM.
MOV CX,WORD PTR idt_eprom + ; limit of eprom IDT
INC CX
SHR CX,
CLD
REP MOVS WORD PTR ES:[EDI],WORD PTR DS:[ESI]
; switch to RAM GDT and IDT
;
LIDT IDT_pword
LGDT GDT_pword
;
MOV BX,GDT_ALIAS ; point DS to GDT alias
MOV DS,BX
;
; copy eprom TSS to RAM
;
MOV BX,INIT_TSS_A ; INIT TSS A descriptor base
; has RAM location of INIT TSS.
MOV ES,BX ; ES points to TSS in RAM
MOV BX,INIT_TSS ; get inital task selector
LAR DX,BX ; save access byte
MOV [BX].access,DS_ACCESS ; set access as data segment
MOV FS,BX ; FS points to eprom TSS
XOR si,si ; FS:si points to eprom TSS
XOR di,di ; ES:di points to RAM TSS
MOV CX,[BX].lim_0_15 ; get count to move
INC CX
;
; move INIT_TSS to RAM.
REP MOVS BYTE PTR ES:[di],BYTE PTR FS:[si]
MOV [BX].access,DH ; restore access byte
;
; change base of INIT TSS descriptor to point to RAM.
MOV AX,INIT_TSS_A_OFFSET.bas_0_15
MOV INIT_TSS_OFFSET.bas_0_15,AX
MOV AL,INIT_TSS_A_OFFSET.bas_16_23
MOV INIT_TSS_OFFSET.bas_16_23,AL
MOV AL,INIT_TSS_A_OFFSET.bas_24_31
MOV INIT_TSS_OFFSET.bas_24_31,AL
;
; change INIT TSS A to form a save area for TSS on first task
; switch. Use RAM at location 0.
MOV BX,INIT_TSS_A
MOV WORD PTR [BX].bas_0_15,
MOV [BX].bas_16_23,
MOV [BX].bas_24_31,
MOV [BX].access,TSS_ACCESS
MOV [BX].gran,O
LTR BX ; defines save area for TSS
;
; copy eprom LDT to RAM
MOV BX,INIT_LDT_A ; INIT_LDT_A descriptor has
; base address in RAM for INIT_LDT.
MOV ES,BX ; ES points LDT location in RAM.
MOV AH,[BX].bas_24_31
MOV AL,[BX].bas_16_23
SHL EAX,
MOV AX,[BX].bas_0_15 ; save INIT_LDT base (ram) in EAX
MOV BX,INIT_LDT ; get inital LDT selector
LAR DX,BX ; save access rights
MOV [BX].access,DS_ACCESS ; set access as data segment
MOV FS,BX ; FS points to eprom LDT
XOR si,si ; FS:SI points to eprom LDT
XOR di,di ; ES:DI points to RAM LDT
MOV CX,[BX].lim_0_15 ; get count to move
INC CX
;
; move initial LDT to RAM
REP MOVS BYTE PTR ES:[di],BYTE PTR FS:[si]
MOV [BX].access,DH ; restore access rights in
; INIT_LDT descriptor
;
; change base of alias (of INIT_LDT) to point to location in RAM.
MOV ES:[INIT_LDT_ALIAS].bas_0_15,AX
SHR EAX,
MOV ES:[INIT_LDT_ALIAS].bas_16_23,AL
MOV ES:[INIT_LDT_ALIAS].bas_24_31,AH
;
; now set the base value in INIT_LDT descriptor
MOV AX,INIT_LDT_A_OFFSET.bas_0_15
MOV INIT_LDT_OFFSET.bas_0_15,AX
MOV AL,INIT_LDT_A_OFFSET.bas_16_23
MOV INIT_LDT_OFFSET.bas_16_23,AL
MOV AL,INIT_LDT_A_OFFSET.bas_24_31
MOV INIT_LDT_OFFSET.bas_24_31,AL
;
; Now GDT, IDT, initial TSS and initial LDT are all set up.
;
; Start the first task!
'
JMP ENTRY_POINTER
RESET_CODE ends
END START, SS:DUMMY,DS:DUMMY

最新文章

  1. SharePoint 2013 搜索高级配置(Search Scope)
  2. kubernetes多节点部署解析
  3. Nginx 笔记与总结(11)Nginx + php-fpm + MySQL 安装 ecshop
  4. goLang文件遍历
  5. DDoS-Deflate安装及配置
  6. 统计网卡TX(发送)RX(接受)流量脚本
  7. pcduino v2安装opencv2.4.8
  8. RCP:如何把Preferences中的项从一个类别移动到另一个类别 2013-08-23 18:59 by Binhua Liu,
  9. IT人常用的网站
  10. springMVC web项目 对访问数据库的用户名密码进行加密解密
  11. [C#]使用 C# 编写自己的区块链挖矿算法
  12. Composer更新慢的解决方案
  13. pythone函数基础(11)读,写,修改EXCEL
  14. txt文本处理---行未添加逗号
  15. Hudson管理平台自动化部署war包
  16. Expm 10_2 实现Ford-Fulkerson算法,求出给定图中从源点s到汇点t的最大流,并输出最小割。
  17. wincc项目移植和复制解决办法
  18. Luogu2045 方格取数加强版(K取方格数) 费用流
  19. Mybatlis SQL 注入与防范
  20. [HAOI2010]订货 BZOJ2424

热门文章

  1. Override is not allowed when implementing interface method Bytecode Version Overriding and Hiding Methods
  2. HDU1176 免费馅饼 —— DP
  3. YTU 2845: 编程题AB-卡片游戏
  4. Iphone 启动图的尺寸
  5. P3239 [HNOI2015]亚瑟王 期望dp
  6. SOLID总结(未完待续)
  7. 转载别人的ognl
  8. bzoj 4584: [Apio2016]赛艇【dp】
  9. VI/VIM修改Tab为4个空格
  10. (图论)51NOD 1264 线段相交