80x86汇编编程-1(续)
看清寄存器、寻址方式与段机制如何协同,掌握实模式地址拼接的边界
按 空格/→ 演示下一步
全部页面点击任意一页,跳回舞台从这页播放
80x86汇编编程-1(续)
看清寄存器、寻址方式与段机制如何协同,掌握实模式地址拼接的边界
汇编编程示例-递归调用
求 n! 时数学上拆成 n × (n-1)!,这叫递归。C 里 factorial(n-1) 是「自己调自己」,汇编里没这魔法——靠 call 反复压栈,每层独立栈帧。
每次「自己调自己」就是拆开套娃再装回去;最里层就是终止条件
汇编编程示例-文件处理-1
递归操作的是内存里的数据,程序一关就消失。文件操作解决「持久化」——汇编靠 DOS 中断 INT 21h 完成这整套服务。
句柄=借书证,INT 21h=服务台,读写=翻页抄录,关闭=还书销证
汇编编程示例-文件处理-2
上一页用 INT 21h 完成了打开、顺序读写、关闭文件。但实际中常常要「跳到指定位置再读」、改文件属性,或者删除、重命名——这些进阶操作才是文件处理-2 的目标。
书签插在哪,下次就从哪里继续;不必像顺序读那样从头一页一页翻
汇编编程示例-文件处理-3
前两页的3Fh/40h只能顺序读写——要拿到第100条记录,难道要把前面99条全读完再跳过?本页用文件指针实现随机定位。
翻书直接跳到第N页≠一页一页翻;AL=0从封面开始数,AL=2从封底倒数
汇编编程示例-文件处理-4
前面学过用 INT 21h 打开、读写、关闭文件。但读大文件时每次都从开头顺序扫描太慢——这一页要掌握文件指针的移动,实现随机访问。
书签=文件指针;翻到指定页=按偏移定位,三种翻法对应三种基准
Vid汇编编程示例-文件处理
前几页都是从文件头顺序读——但若只想拿文件中第1000字节的数据,难道要把前面999字节全读一遍再丢掉吗?显然有更聪明的办法。
书签标记当前位置,seek 就是移动书签到新位置
汇编编程示例-文件处理-6
前几页处理文件都是从头到尾顺序读写,像听磁带走带。但查数据库、修改文件中间某段、日志回查某行——这些场景需要直接跳到指定位置。这就是随机文件访问。
书签定位不用从第一页翻起,指针定位也不用从头读
汇编编程示例-文件处理-7
想象你和同事同时改同一份表格——谁先保存,后保存的就覆盖前一个人的内容。汇编里多个程序访问同一个文件,也会撞上同样的麻烦。
「只读」= 读模式打开,「禁止编辑」= deny write 模式
汇编编程示例-文件处理-8
上节顺序读文件像从头翻书看小说,但若要直接打开第 500 章,从头翻就不现实。本节讲文件随机访问——把『书签』直接夹到目标位置。
书签停在当前页,翻书后书签跟着走;Seek 就是把书签强行夹到任意页
汇编编程示例-共享库文件
文件处理函数如果每次都写进每个程序,磁盘和内存都吃不消。多个程序想共用同一份 printf 怎么办?这就是共享库要解决的问题。
多个程序像读者共用一本书,而非每人复印一份
本节要点
- ✓递归靠栈帧隔离,EBP/RBP锚定参数与局部变量
- ✓文件处理本质是缓冲管理+系统调用约定
- ✓共享库要求位置无关代码,GOT/PLT做间接寻址
- ✓栈帧不平衡、句柄未关是最常见的崩溃源
课后思考
先独立想,再对照参考答案。三题对应三个层次,由浅入深。
参考答案系统调用不保证保留 EAX/ECX/EDX 等寄存器,所以调用方必须保存现场。文件描述符本质是进程文件描述符表中的索引,关闭后会被复用。
参考答案lseek 的偏移是 32 位有符号整数,2GB+ 需分多次 seek 拼接或用 64 位扩展调用;同时要注意 SEEK_SET/SEEK_CUR/SEEK_END 三种模式的语义差别。
参考答案若汇编用寄存器传参,C 从栈上读到的是垃圾值;若汇编按 stdcall 自己清栈而 C 仍按 cdecl 再清,栈会不平衡甚至崩溃。ABI 是两者必须签的'合同'。