汇编语言程序
3.1 用汇编语言写的源程序
3.1.1 用灰白你语言编写程序的工作过程
3.1.2 程序中的三种伪指令
3.1.3 源程序经编译连接后变为机器码
3.1.4 汇编程序的结构
3.1.5 写出一个程序来
3.2 由源程序到程序运行
3.2.1 编辑源程序
直接使用记事本来编辑源文件,因为大佬都是用的记事本,编辑好以后直接保存。最后把文件的后缀改成asm。
3.2.2 编译
编译成功以后就会在挂载的目录下生成一个目标文件p4-1.obj。
生产obj文件以后使用内置工具link来进行连接操作,生成exe可执行文件。
最后来执行可执行的exe文件,直接输入可执行文件的名称就行。
3.3 运行及跟踪
3.3.1 用debug装载程序
查看代码,cx寄存器存储的内容是整个程序代码占多少给字节。
3.3.2 用debug单步执行
debug p4-1.exe只是将这个可执行文件给挂载到了这个debug调试程序,并不是已经执行了的。想要执行在这里面的命令需要我们自己去手动执行。
其中的int 21 代表着程序已经执行完了。
我们除了使用这个t命令也使用p命令与g命令来进行执行程序。
3.3.3 程序执行的不同方式
3.4 符号【...】和(...)
3.4.1 【...】的规定和(...)的约定
3.4.2 符号idata表示常量
3.4.3 案例分析
debug # 运行debug程序
# 修改 指定物理地址的内容
e 2100:0
be 00
# 开始在cs 寄存器中传入指令代码
a
mov ax,2000 # 将2000h这个16进制的内容传入ax通用寄存器
mov ds,ax # 将ax的内容传入ds段寄存器
mov bx,1000 # 将1000h这个16进制的内容传入bx通用寄存器
mov ax,[bx] # 将以ds作为段地址以bx作为偏移地址的物理地址的内容替换掉ax的内容
inc bx # bx的内容自增1
inc bx # bx的内容自增1
mov [bx],ax # 将 ax通用寄存器的内容替换掉将以ds作为段地址以bx作为偏移地址的物理地址的内容
inc bx # bx的内容自增1
inc bx # bx的内容自增1
mov [bx],ax # 将 ax通用寄存器的内容替换掉将以ds作为段地址以bx作为偏移地址的物理地址的内容
inc bx # bx的内容自增1
mov [bx],al # 将al寄存器的字节内容也就是ax中低字节内容替换掉将以ds作为段地址以bx作为偏移地址的物理地址的内容
inc bx # bx的内容自增1
mov [bx],al # 将al寄存器的字节内容也就是ax中低字节内容替换掉将以ds作为段地址以bx作为偏移地址的物理地址的内容
3.5 Loop指令
使用记事本将程序编写了,并且使用masm命令与link命令来将程序文件给编译并连接了。
assume cs:code
code segment
mov ax,2
mov cx,11
s: add ax,ax
loop s # 这条指令是跳转到这个s:的地址位置,每执行一次cx的值就会减一直到减到零时就会执行之后的指令mov ax,4c00h
int 21h
code ends
end
3.6 段前缀的使用
3.6.1 引入段前缀:一个“异常”现象及对策
3.6.2 访问连续的内存单元--loop和[bx]联手
3.6.2.1 程序:计算ffff:0~ffff:b单元中的数据和,结果存储在dx中
assume cs:code
code segment
mov ax,ffffh
mov ds,ax
mov cx,12
mov dx,0
mov bx,0s: mov al,ds:[bx]
mov ah,0
add dx,ax
inc bx
loop smov ax,4c00h
int 21h
code ends
end
3.6.2.2 段前缀的使用
3.7 在代码段中使用数据
问题:直接使用物理地址来指定存放数据是不太安全的,我们可以使用代码段来自定义存放数据。
应用案例:
在cs指令寄存器中前面16个字节都是我们定义的数据,后面的都是代码指令
案例里面的代码还是有问题, 因为如果在debug里面观察的话,是直接从段地址的0偏移地址就开始存储代码指令了,因该从10这个偏移地址开始。
改进:
3.8 在代码段中使用栈
我们在dos系统中去完成这个过程(借用栈这个存储方式来将一些数据给逆存放):
先使用记事本来输入:
assume cs:codesg
codesg segment# 用cs为段地址分配给48个地址来存放内容
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0start:mov ax,cs
mov ss,ax # 栈的顶部为cs这个段地址的值
mov sp, 30h # 规定栈的底部偏移地址
mov bx,0
mov cx,8
s: push cs:[bx] # 入栈,将cs段bx偏移地址的内容放入栈中
add bx,2
loop smov bx,0
mov cx,8
s0: pop cs:[bx] # 出栈,栈中的内容放入到cs段bx偏移地址
add bx,2
loop s0mov ax,4c00h
int 21h
codesg ends
end start
查看到cs为段地址的前48位的内容,0-15位为我们自己定义的内容,16-47位为我们为栈分配好的空间: