mark 一下, 2023.Aug.15 从湖北返回学习,参加了一场学术会议, 看来做学术确实是需要交流的, 尤其该领域的多交流, 还是需要至少一年参加一次学术会议.
不至于让自己太孤陋寡闻, 局限于自己狭隘的领域内,多看看目前学术界的进展.
1. 用汇编语言写的源程序
1.1 用汇编语言编写程序的工作过程
汇编程序:包含汇编指令和伪指令的文本’
-
汇编指令,对应有机器码的指令,可以被编译为机器指令,最终被
CPU执行. -
伪指令
没有对应的机器码的指令,最终不被CPU所执行。
:谁来执行伪指令呢?
伪指令是由编译器来执行的指令,编译器根据伪指令来进行相关的编译工作.
assume cs:codesg
codesg segment
mov ax,0123H
mov bx,0456H
add ax,bx
add ax,ax
mov ax,4c00h
int 21h
codesg ends
end
程序返回(套路!):程序结束运行后,将CPU的控制权交还给使它得以运行的程序(常为DOS系统)
1.2程序中的三种伪指令
- assume(假设)
; 含义是假设某一段寄存器和程序中的某一个用 segment … ends 定
义的段相关联——assume cs:codesg指CS寄存器与codesg关联,将
定义的codesg当作程序的代码段使用。
- 段定义
; 一个汇编程序是由多个段组成的,这些段被用来存放代码、数据或当作栈空间来使用。
; 一个有意义的汇编程序中至少要有一个段,这个段用来存放代码。
; 定义程序中的段:每个段都需要有段名
段名 segment ——段的开始
…
段名 ends ——段的结束
- end (不是ends)
汇编程序的结束标记。若程序结尾处不加end,编译器在编译程序时,无法知道程序在何处结束。
assume cs:codesg
codesg segment
mov ax,0123H
mov bx,0456H
add ax,bx
add ax,ax
mov ax,4c00h
int 21h
codesg ends
end
1.3 源程序经编译连接后变为机器码
1.4 汇编程序的结构
- 在Debug中直接写入指令编写的汇编程序
; 适用于功能简单、短小精悍的程序
; 只需要包含汇编指令即可
- 单独编写成源文件后再编译为可执行文件的程序
; 适用于编写大程序
; 需要包括汇编指令,还要有指导编译器工作的伪指令
; 源程序由一些段构成,这些段存放代码、数
据,或将某个段当作栈空间
assume cs:code,ds:data,ss:stack
data segment
dw 0123H,0456H,0789H,0abcH,0defH
data ends
stack segment
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
stack ends
code segment
mov ax,stack
mov ss,ax
mov sp,20h ;设置栈段
mov ax,data
mov ds,ax ;设置数据段
mov bx,0
mov cx,8
s: push [bx]
add bx,2
loop s
....
code ends
end
; 分号,用来代表-- 注释
1.5 如何写出一个程序来?
例:编程求 2^3。
①定义一个段
②实现处理任务
③指出程序在何结束
④段与段寄存器关联
⑤加上程序返回的代码
1.6程序中可能的错误
语法错误
; 程序在编译时被编译器发现的错误;
; 容易发现下面程序中错误
aume cs:abc
abc segment
mov ax,2
add ax,ax
add ax,sx
end
逻辑错误
; 程序在编译时不能表现出来的、在运行时
发生的错误;
; 不容易发现下面程序中的错误
assume cs:abc
abc segment
mov ax,2
add ax,ax
add ax,bx
mov ax,4c10H
int 21H
abc ends
end
求 2^
2. 由源程序到程序运行
2.1 由写出源程序到执行可执行文件的过程
2.2 编辑源程序
2.3 编译
-
目标文件(*.OBJ)是我们对一个源程序进行编译要
得到的最终结果。 -
列表文件(*.LST)是编译器将源程序编译为目标文件的过程中产生的中间结果。
-
交叉引用文件(*.CRF)同列表文件一样,是编译器将源程序编译为目标文件过程中产生的中间结果。
-
对源程序的编译结束,编译器输出的最后两行告诉我们这个源程序没有警告错误和必须要改正的错误。
两类错误
û Severe Errors
û 找不到所给出的
源程序文件。
命令后加 ; 以简化过程
2.4 连接
-
可执行文件(.EXE)是我们对一个程序进行连接要得到的最终结果。
-
映像文件(.MAP)是连接程序将目标文件连接为可执行文件过程中产生的中间结果。
-
库文件(.LIB)里包含了一些可以调用的子程序,如果我们的程序中调用了某一个库文件中的子程序,就需要在连接的时候,将这个库文件和我们的目标文件连接到一起,生成可执行文件。
-
no stack segment,一个“没有栈段”的警告错误 ,可以不理会这个错误。
:连接中可能会遭遇错误
:例:object nor found —— 找不到对象
2.5 执行可执行程序
我们的程序没有像显示器输出任何信息。程序只是做了一些将数据送入寄存器和加法的操作,而这些事情,我们不可能
从显示屏上看出来。
:程序执行完成后,返回,屏幕上再次出现操作系统的提示符。
2.6 小结
源文件
.asm
目标文件
.obj
目标文件
.obj
可执行文件
.exe
3. 用Debug跟踪程序的执行
3.1 用Debug装载程序
小结
程序加载后,DS中存放着程序所在内存区的段地址,这个内存区的偏移地址为 0 ,则程序所在的内存区的地址为:DS:0。
这个内存区的前256 个字节存PSP,DOS用来和程序进行通信。
从 256字节处向后的空间存放的是程序,CS的值为DS+10H。
; 程序加载后,CX中存放代码的长度(字节)。
程序被装入内存的什么地方?
3.2 用Debug单步执行程序
3.3 其他方式执行
-
继续命令P(Proceed):
类似T命令,逐条执行指令、显示结果。但遇子程序、中断等时,直接执行,然后显示结果。 -
运行命令G(Go):从指定地址处开始运行程序,直到遇到断点或者程序正常结束。
3.4 程序执行的不同方式
- 在DOS中执行
程序执行的“常态”
- DOS启动后,计算机由“命令解释器”(程序command.com)控制;
- 运行可执行程序时,command将程序加载入内存,设置CPU的CS:IP指向程序的第一条指令(即程序的入口),使程序得以运行。
- 程序运行结束后,返回到“命令解释器”,CPU继续运行command。
- 在Debug中执行
程序执行处于开发周期的运行方式;
运行Debug时,command程序加载Debug.exe,debug 将程序加载入内存,程序运行结束后,
要返回到Debug中,使用Q命令退出Debug,将返回到command中。