一个汇编语言程序
codesg segment
st: mov ax,0123h mov bx,0456h add ax,bx add ax,ax
mov ax,4c00
int 21h
codesg ends
end st
; end命令除了通知编译器程序结束外,还可以通知编译器程序入口在什么地方。 ; 如上述的 end st,st就是一个入口说明符
涉及到的一些知识:
- segment
xxx segment ;code … xxx ends
- segment和ends是一对伪指令关键字,用来定义一个段。
- 一个汇编程序是由多个段组成的,这些段被用来存放代码、数据、或者当作栈空间来使用。一个有意义的汇编程序至少要有一个段,用来存放代码。
- end
- end汇编语言的结束标记。在编译过程中,如果遇到end指令,就结束编译
- assume
- assume 假设,假设某一个段寄存器和程序中的一个段关联。
- 可以理解为用来将特定用途的段和相关寄存器关联起来
- 标号(codesg)
- 一个标号代表一个地址
- 程序返回mov ax,4c00 int 21
- 暂时记住这两条指令代表程序返回
注:在Debug中,最后的int 21指令要使用P命令执行。
<a name="sPo66"></a>
## 编译和连接方法
![image.png](https://cdn.nlark.com/yuque/0/2022/png/21879589/1656340199649-460c038c-d39b-447f-a8cc-27e9d627bc44.png#clientId=u97389917-71f9-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=182&id=u795ec07c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=227&originWidth=647&originalType=binary&ratio=1&rotation=0&showTitle=false&size=52430&status=done&style=none&taskId=uc36f62db-2d0a-4b38-9359-d897e602412&title=&width=517.6)![image.png](https://cdn.nlark.com/yuque/0/2022/png/21879589/1656340222116-0bc8ae39-551c-4cb6-bb14-c8daa8865064.png#clientId=u97389917-71f9-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=647&id=u5ee843eb&margin=%5Bobject%20Object%5D&name=image.png&originHeight=809&originWidth=580&originalType=binary&ratio=1&rotation=0&showTitle=false&size=317859&status=done&style=none&taskId=ue3ee4548-509b-4df8-9742-6e8a15ebb3d&title=&width=464)![image.png](https://cdn.nlark.com/yuque/0/2022/png/21879589/1656340375220-631ce0f6-ff5a-4311-82a4-203d0d1b9efe.png#clientId=u97389917-71f9-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=662&id=u5ba86dec&margin=%5Bobject%20Object%5D&name=image.png&originHeight=827&originWidth=571&originalType=binary&ratio=1&rotation=0&showTitle=false&size=301837&status=done&style=none&taskId=u4a30135a-0f71-4f4e-8976-b680fad635f&title=&width=456.8)![image.png](https://cdn.nlark.com/yuque/0/2022/png/21879589/1656340271356-a74e96de-1fe3-4825-bb9a-261ab9928c96.png#clientId=u97389917-71f9-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=647&id=u2e8d91ee&margin=%5Bobject%20Object%5D&name=image.png&originHeight=809&originWidth=576&originalType=binary&ratio=1&rotation=0&showTitle=false&size=291692&status=done&style=none&taskId=u98f74dc8-1bc8-4de2-abdd-de7a18df40b&title=&width=460.8)![image.png](https://cdn.nlark.com/yuque/0/2022/png/21879589/1656340344956-d35986c0-1ada-4a00-b6d6-7a91fab1df19.png#clientId=u97389917-71f9-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=667&id=u60dde465&margin=%5Bobject%20Object%5D&name=image.png&originHeight=834&originWidth=570&originalType=binary&ratio=1&rotation=0&showTitle=false&size=310450&status=done&style=none&taskId=ue18bc55f-8d5e-4a74-b2fd-80d398a3931&title=&width=456)![image.png](https://cdn.nlark.com/yuque/0/2022/png/21879589/1656340316254-284ca234-a274-45f4-8205-d85f3a958394.png#clientId=u97389917-71f9-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=657&id=u93f8c089&margin=%5Bobject%20Object%5D&name=image.png&originHeight=821&originWidth=575&originalType=binary&ratio=1&rotation=0&showTitle=false&size=333976&status=done&style=none&taskId=uc3758d4f-19f5-4d15-be38-563269f324b&title=&width=460)![image.png](https://cdn.nlark.com/yuque/0/2022/png/21879589/1656340400978-6c1706cf-e811-4d12-94f2-088db194a609.png#clientId=u97389917-71f9-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=188&id=u709bfc60&margin=%5Bobject%20Object%5D&name=image.png&originHeight=235&originWidth=576&originalType=binary&ratio=1&rotation=0&showTitle=false&size=117900&status=done&style=none&taskId=u8ff77f7e-2262-41ef-998c-fe409304795&title=&width=460.8)<br />注:编译器只能发现语法错误而无法发现逻辑错误。
CPU执行一个程序,需要有另一个程序将它加载进内存(即将CS:IP指向它),一般情况下我们通过DOS执行这个.exe,所以是DOS程序将它加载进入内存。当这个程序运行结束,再返回DOS程序继续执行。如果是DOS调用Debug调用.exe,那么先返回Debug再返回DOS。
DOS加载一个.exe时,先在内存中找到一段内存,起始段地址SA,然后分配256字节的PSP区域,用来和被加载程序通信。在之后的段地址SA+10就是程序开始的段地址。CS:IP指向它,DS=SA。
<a name="wRvcG"></a>
## 程序结构
汇编程序的几个基本要素和简单框架如下:
1. 首先是要定义一个段,如abc。并在段中写入指令和数据
abc segment ; code … abc ends ```
- 用end关键词来指定结束位置
- 将段和指定的段寄存器绑定起来