汇编入门笔记(五)

0x10:源程序

标号:就是xxx segment和xxx ends定义的段中的xxx,它就是段名,最终将处理为一个段的段地址。

程序返回:

image-20210926213138434

1
2
mov ax, 4c00H 
int 21H ;这两条指令实现程序的返回

在第一个程序中的这两条指令实现程序返回。

image-20210926213506968

程序的编译、连接和执行:

编写一个test.asm文件,

编译:masm test.asm,连接:link test.obj,执行:test.exe

简化编译、连接过程:在每条编译、连接命令之后加上分号。

0x11:程序执行过程跟踪

通过debug工具来跟踪 test.exe 程序的执行过程:

image-20210927094226522

发现 CS:IP 指向程序的入口,CX 寄存器存放程序的长度,也就是机器码(汇编指令转成机器码)的长度。

为什么DS的内容比CS少10H?

这涉及到DOS系统中 .EXE 文件中的程序的加载过程:

image-20210927130840428

程序加载后,ds 存放程序所在内存的段地址,也就是PSP的段地址。

由于PSP占据了10H的内存,所以程序的物理地址是 [ds]+10H:0,这个段地址就是 cs 的内容。

u命令可以将机器指令都翻译成汇编指令。

然后用t命令单步执行。注意到int 21时,要用p命令执行!

q命令退出debug。

0x12:[bx] 和loop 指令

[bx] 的含义:[bx](和[0]类似)同样表示一个内存单元,它的偏移地址在bx中,段地址默认在ds中

image-20210927141409691

loop指令的格式是:loop 标号,CPU执行loop指令的时候,要进行两步操作,

  1. (cx) = (cx) - 1; cx 存放loop循环的循环次数
  2. 判断 cx 中的值,不为零则转至标号处执行程序,如果为零则向下执行。

定义一个描述性的符号:“()”,它用来表示一个寄存器或一个内存单元的内容。

image-20210927141626563

约定用符号 idata 表示一个常量,如:mov ax,[idata]表示将 ds:idata 处的数据送入 ax寄存器。

计算2^12:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
assume cs:code 

code segment
mov ax, 2

mov cx, 11 ;循环次数
s: add ax, ax
loop s ;在汇编语言中,标号代表一个地址,标号s实际上标识了一个地址,
;这个地址处有一条指令:add ax,ax。
;执行loop s时,首先要将(cx)减1,然后若(cx)不为0,则向前
;转至s处执行add ax,ax。所以,可以利用cx来控制add ax,ax的执行次数。

mov ax,4c00h
int 21h
code ends
end

image-20210927142403465

debug的g命令,如g 0016,将从 cs:ip 位置执行指令到 cs:0016 位置。

不用一步步单步执行了。

0x13:debug 和汇编编译器 masm 对指令的不同处理

image-20210927142941345

image-20210927143043918

0x14:[bx] 和loop 指令的联合应用

计算 ffff:0~ffff:b 单元中数据的和,结果存储在 dx 中。

注意:每个单元中存放的是8位数据,而 dx 是一个16位寄存器,需要将 ah 置零,将 al 放8位数据,二者拼起来就是一个16位数据。

image-20210927150848122

解释:inc bx就是将 bx 中的内容自增1。

0x15:段前缀

1
2
3
4
5
6
mov ax, ds:[bx]
mov ax, cs:[bx]
mov ax, ss:[bx]
mov ax, es:[bx] ; 只有bx寄存器能作为偏移地址
mov ax, ss:[0]
mov ax, cs:[0]

这些出现在访问内存单元的指令中,用于显式地指明内存单元的段地址的“ds:”,“cs:”,“ss:”,“es:”,在汇编语言中称为段前缀。

将内存ffff:0 ~ ffff:b单元中的数据复制到0:200 ~ 0:20b单元中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
assume cs:code 

code segment
mov ax, 0ffffh
mov ds, ax ;(ds)= 0ffffh
mov ax, 0020h
mov es, ax ;(es)= 0020h 0:200 等效于 0020:0
mov bx, 0 ;(bx)= 0,此时ds:bx指向ffff:0,es:bx指向0020:0

mov cx,12 ;(cx)=12,循环12次
s: mov dl,[bx] ;(d1)=((ds)* 16+(bx)),将ffff:bx中的字节数据送入dl ,段地址默认为ds
mov es:[bx],dl ;((es)*16+(bx))=(d1),将dl中的数据送入0020:bx
inc bx ;(bx)=(bx)+1
loop s

mov ax,4c00h
int 21h
code ends
end
坚持原创技术分享,您的支持将鼓励我继续创作!