c09 用户程序 — 主逻辑框图
c09.asm · SECTION code_1 / code_2 · 段间控制转移
《x86汇编语言:从实模式到保护模式》· 李忠
第9章 · 用户程序 (第1页 / 共2页)
code_1 段执行流程
code_2 段执行流程
子程序调用
段间跳转(retf)
顺序执行
跨段控制转移
SECTION code_1 vstart=0 · align=16 进入 start 时寄存器状态 CS→code_1 DS=ES→header SS→加载器栈 由加载器 jmp far [0x04] 跳入 start(入口点) ① SS ← [stack_segment](header[0x1c]) SP ← stack_end(= 0x100) ② DS ← [data_1_segment](header[0x14]) 显示 msg0 BX ← msg0 偏移 call put_string(DS:BX) 远跳转到 code_2:begin push [es:code_2_segment] → CS push begin(偏移) → IP retf → 跳入 code_2:begin continue(code_2 远跳回此处) DS ← [es:data_2_segment](header[0x18]) ES 仍指向 header 显示 msg1 BX ← msg1 偏移 call put_string(DS:BX) jmp $(原地循环,程序结束) SECTION code_2 vstart=0 · align=16 begin push [es:code_1_segment] → CS push continue(偏移) → IP retf → 跳回 code_1:continue (ES 始终保留 header 指针) retf 远跳 retf 远跳回 put_string 输入:DS:BX = 字符串首地址 逐字节读取,遇0终止 每字符 call put_char 显示 call call ES 始终保留 header 指针 进入时 ES = header 段(加载器设置) start 只改 SS、DS,ES 保持不动 通过 es: 前缀访问 header 各段地址字段 [es:code_2_segment] [es:data_2_segment]
c09 用户程序 — 打印字符逻辑框图
c09.asm · put_string / put_char · VGA文本模式字符输出
《x86汇编语言:从实模式到保护模式》· 李忠
第9章 · 用户程序 (第2页 / 共2页)
put_string
put_char 主流程
滚屏处理
判断分支
put_string 输入:DS:BX=字符串首地址 CL ← [DS:BX] 从字符串取一个字节 CL == 0? 字符串结尾? ret(返回调用者) call put_char(CL) 显示当前字符 BX++ → 下一个字符 循环 call put_char 输入:CL = 字符 ASCII 码 push ax bx cx dx ds es(保存寄存器) 读取光标位置 → BX 0x3D4←0x0E, 0x3D5→AH(高8位) 0x3D4←0x0F, 0x3D5→AL(低8位) BX=AX CL == 0x0D? 回车符 CR? 回车处理 BX÷80×80 →行首位置 直接→set_cursor CL == 0x0A? 换行符 LF? 换行处理 BX += 80 普通字符写入显存 ES=0xB800,[ES:BX×2] ← CL BX++(光标前进一格) BX ≥ 2000? 光标超出屏幕? 滚屏处理 DS=ES=0xB800 rep movsw:0xA0→0x00,搬移1920字 清末行:[ES:3840~] ← 0x0720 ×80次 BX -= 80(光标上移一行) 设置光标位置(set_cursor) 0x3D4←0x0E,0x3D5←BH(高8位) 0x3D4←0x0F,0x3D5←BL(低8位) pop es ds dx cx bx ax ret(返回 put_string)