[042][x86汇编语言]第十五章 习题1解答:切换任务 co
2018-07-03 本文已影响14人
AkuRinbu
学习笔记
《x86汇编语言:从实模式到保护模式》
https://www.jianshu.com/p/d481cb547e9f
本章习题一
1.修改本章的源程序,使之能够顺序完成以下工作:
① 从程序管理器任务切换到任务A,显示消息后返回程序管理器;
② 从程序管理器任务切换到任务B,显示消息后返回程序管理器;
③ 再从程序管理器任务切换到任务A,显示另一条消息,然后返回程序管理器;
④ 再从程序管理器任务切换到任务B,显示另一条消息,然后返回程序管理器;
解题思路
- 题目要求的任务切换顺序是 :
内核->任务A
->内核->任务B
->内核->任务A(另一条消息)
->内核->任务B(另一条消息)
->内核
- 不太符合题意的我的解法:
内核->任务A(LBA:50)
->内核->任务B(LBA:100)
->内核->任务A(LBA:50)(另一条消息)
->内核->任务B(LBA:100)(另一条消息)
->内核
- 说明
如果题目要求的 任务A 是指 只能从 硬盘加载一次,那么我做不来了...
我的解法是可以从 硬盘 同一个位置 比如LBA:50 处加载多次...
不是真正的 `一个任务A` ,而是使用了相同源码的 任务 A1 A2...
本质上来说,同一个用户程序源文件 taskA.asm(taskA.bin),
使用load_relocate_program 两次加载到内存后,是放在内存中两个完全不同的地方的,
是风牛马不相及的两个完全全不同的、相互独立的两个任务,只是使用了同一段源码而已。
代码使用
准备工作,源码文件
- 加载程序使用配书代码包里的
c13_mbr.asm
- 内核程序文件
ex15-1_core.asm
(修改自:内核程序c15_core.asm
) -
任务A文件
ex15-1_A.asm
(修改自:用户程序c15.asm
) -
任务B文件
ex15-1_B.asm
(修改自:用户程序c15.asm
)
代码编译、运行
- 1、nasmide.exe编译全部源文件,得到
XXX.bin
二进制文件; - 2、fixvhdwr.exe把二进制文件写入虚拟硬盘
c13_mbr.bin LBA: 0
ex15-1_core.bin LBA: 1
ex15-1_A.bin LBA: 50
ex15-1_B.bin LBA: 100
- 3、运行虚拟机 VM VirtualBox
第15章 习题1 运行结果.png
代码修改
用户程序(任务A : ex15-1_A.asm
,任务B:ex15-1_B.asm
)
- 1、头部段 增加 字段 存放 控制消息显示的参数
mss_type dd 0 ;#0x328
- 2、数据段 不同的消息 内容
ex15-1_A.asm
mss_1 db '[USER TASK]:>>>>> A: 1st <<<<<',0x0d,0x0a,0
mss_2 db '[USER TASK]:>>>>> A: 2nd <<<<<',0x0d,0x0a,0
ex15-1_B.asm
mss_1 db '[USER TASK]:***** B: 1st *****',0x0d,0x0a,0
mss_2 db '[USER TASK]:***** B: 2nd *****',0x0d,0x0a,0
- 3、代码段 根据消息控制参数 显示不同的消息
mov edx,[fs:mss_type]
cmp edx,1
jne .mss2
mov ebx,mss_1
call far [fs:PrintString]
jmp .mssend
.mss2:
mov ebx,mss_2
call far [fs:PrintString]
.mssend:
内核程序 ex15-1_core.asm
- 1、任务切换代码(位于代码段 start标号后,就是在
ltr cx
后面)
;------------------------------------------------------
;任务A 消息1
mov ecx,0x46
call sys_routine_seg_sel:allocate_memory
call append_to_tcb_link
push dword 1 ;用户程序消息显示参数 1:消息1 2:消息2
push dword 50 ;任务A程序位于 LBA:50
push ecx
call load_relocate_program
call far [es:ecx+0x14]
;------------------------------------------------------
;程序管理器重新获得控制权
mov ebx,prgman_msg4
call sys_routine_seg_sel:put_string
;------------------------------------------------------
;任务B 消息1
mov ecx,0x46
call sys_routine_seg_sel:allocate_memory
call append_to_tcb_link
push dword 1 ;用户程序消息显示参数 1:消息1 2:消息2
push dword 100 ;任务B程序位于 LBA:100
push ecx
call load_relocate_program
call far [es:ecx+0x14]
;------------------------------------------------------
;程序管理器重新获得控制权
mov ebx,prgman_msg4
call sys_routine_seg_sel:put_string
;------------------------------------------------------
;任务A 消息2
mov ecx,0x46
call sys_routine_seg_sel:allocate_memory
call append_to_tcb_link
push dword 2 ;用户程序消息显示参数 1:消息1 2:消息2
push dword 50 ;任务A程序位于 LBA:50
push ecx
call load_relocate_program
call far [es:ecx+0x14]
;------------------------------------------------------
;程序管理器重新获得控制权
mov ebx,prgman_msg4
call sys_routine_seg_sel:put_string
;------------------------------------------------------
;任务B 消息2
mov ecx,0x46
call sys_routine_seg_sel:allocate_memory
call append_to_tcb_link
push dword 2 ;用户程序消息显示参数 1:消息1 2:消息2
push dword 100 ;任务B程序位于 LBA:100
push ecx
call load_relocate_program
call far [es:ecx+0x14]
;------------------------------------------------------
- 2、修改子程序load_relocate_program,任务切换代码压入了3个参数(依次压入了:
消息控制参数、逻辑扇区号、TCB线性基地址
)
;------------------------------------------
;回填用户程序消息显示参数
mov edx,[ebp+13*4] ;消息显示参数
mov [edi+0x328],edx
;------------------------------------------
子程序load_relocate_program 栈 示意图.png