汇编语言设计程序篇-03
- 用汇编语言写的源程
- 用汇编语言编写程序的工作过程
- 程序中的三种伪指令
- 源程序经编译连接后变为机器码
- 汇编程序的结构
- 如何写出一个程序来?
- 程序中可能的错误
- 由源程序到程序运行
- 由写出源程序到执行可执行文件的过程
- 编译
- 提示语法错误
- 连接
- 执行可执行程序
- 小结
- 由写出源程序到执行可执行文件的过程
- 运行及跟踪
- 用Debug装载程序
- 用Debug单步执行程序
- 其他方式执行
- [...]和(...)
- [...]的规定与(...)的约定
- 再约定:符号idata表示常量
- Loop指令
- 用loop指令编程实例
- Loop指令使用再例
- 段前缀的使用
- 访问连续的内存单元——loop和[bx]联手!
- 程序:计算ffff:0~ffff:b单元中的数据的和,结果存储在dx中
- 段前缀的使用
- 在代码段中使用数据
- 应用案例
- 在代码段中使用栈
- 以数据逆序存放为例
- 数据逆序存放程序
- 在Debug中的执行结果
- 将数据、代码、栈放入不同 段
- 在Debug中执行
本系列文章参考汇编语言第四版和汇编语言程序设计 贺利坚主讲整理而成
用汇编语言写的源程序
用汇编语言编写程序的工作过程
程序中的三种伪指令
CS:IP寄存器是定位代码段位置的
源程序经编译连接后变为机器码
汇编程序的结构
在Debug中直接写入指令编写 的汇编程序
- 适用于功能简单、短小精悍的程序
- 只需要包含汇编指令即可
单独编写成源文件后再编译为可执行文件的程序
- 适用于编写大程序
- 需要包括汇编指令,还要有指导编译器工作 的伪指令
- 源程序由一些段构成,这些段存放代码、数据,或将某个段当作栈空间。
; —注释
如何写出一个程序来?
程序中可能的错误
由源程序到程序运行
由写出源程序到执行可执行文件的过程
编译
提示语法错误
连接
执行可执行程序
小结
运行及跟踪
这一节主要来看看程序加载进内存后的执行过程:
- 先准备一个汇编程序—求2的三次方
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
- 将程序编译为obj对象文件
masm test.asm;
- 将obj文件链接为可执行exe文件
link TEST;
用Debug装载程序
DS寄存器存放的数据段的段地址,CS指向代码段的段地址
用Debug单步执行程序
其他方式执行
[…]和(…)
[…]的规定与(…)的约定
再约定:符号idata表示常量
Loop指令
功能:实现循环(计数型循环)
指令的格式: loop 标号
CPU 执行loop指令时要进行的操作
① (cx)=(cx)-1;
②判断cx中的值 不为零则转至标号处执行程序 如果为零则向下执行。
要求:
- cx 中要提前存放循环次数,因为(cx)影响着 loop指令的执行结果
- 要定义一个标号
用loop指令编程实例
- Loop指令实际就是跳转到标号的地址处
LOOP指令执行会跳转到指定地址处,然后对应的IP寄存器值也会被改变,并且cs值会不断减去一,直到为0时,退出循环
Loop指令使用再例
不能写成add dl al,因为会产生溢出,add dx al更不行
段前缀的使用
- debug调试下,mov al,[0]可以正确按照我们的意图执行,但是在程序中这样写的时候,会存在问题,会将括号里面的值当做常量赋值,这个不是语言的问题,是底层硬件实现的问题
访问连续的内存单元——loop和[bx]联手!
程序:计算ffff:0~ffff:b单元中的数据的和,结果存储在dx中
段前缀的使用
如果不明确指定,那么[0]就表示ds:[0],如果明确指定了,像上面es:[bx],那对应的段地址就默认按照es寄存器中的值为准
在代码段中使用数据
计算机中每一块地址应该用来做什么都是会提前由操作系统规定好的,如果我们随意乱放数据,例如: 我们将数据存放到存放着中断指令的内存位置处,那么不就出大问题了吗?
数据并非只能存放在数据段中,也可以存放在代码段和栈段中
应用案例
上面程序的问题在于,我们将数据放在了代码段的前面,占据了16个字节大小,那么真正的程序代码应该从第17个字节开始,那么就会出现将数据当做指令执行的问题,看下面的例子:
在代码段中使用栈
以数据逆序存放为例
数据逆序存放程序
在Debug中的执行结果
将数据、代码、栈放入不同 段
除了CS寄存器不需要初始化之外,栈相关寄存器和数据段寄存器都需要手动初始化一下