汇编语言学习总结

CALL和RET指令

ret和retf

ret 指令用栈中的数据,修改IP的内容,从而实现近转移;
retf 指令用栈中的数据,修改CS和IP的内容,从而实现远转移。

ret 指令相当于

pop IP

retf 指令相当于

pop IP
pop CS

检测点10.1

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

stack segment
db 16 dup(0)
stack ends

code segment
start: mov ax, stack
mov ss, ax
mov sp, 16
mov ax, 1000h;cs地址
push ax
mov ax, 0 ;ip地址
push ax
retf
;retf指令相当于是pop ip,pop cs
code ends

end start

call指令

  1. call 标号

push IP
jmp near ptr 标号

  1. call far ptr 标号

push CS
push IP
jmp near ptr 标号

  1. call 16位 reg

push IP
jmp 16位 reg

  1. call word ptr 内存单元地址

push IP
jmp word ptr 内存单元地址

  1. call dword ptr 内存单元地址

push CS
push IP
jmp dword ptr 内存单元地址

call和ret的配合使用

call 标号
标号:
指令
ret

mul指令

  1. 两个相乘的数:
    两个相乘的数,要么都是8位,要么都是16位。
    如果是8位,一个默认放在AL中,另一个放在8位reg或内存字节单元中;
    如果是16位,一个默认在AX中,另一个放在16位reg或内存字单元中。
  2. 结果:
    如果是8位乘法,结果默认放在AX中;
    如果是16位乘法,结果高位默认在DX中存放,低位在AX中放。

mul reg
mul 内存单元
mul byte ptr ds:[0]

实验十:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
assume cs:code
data segment
db 10 dup(0)
data ends

code segment
start: mov ax, 12345
mov bx, data
mov ds, bx
mov si, 0
call dtoc

mov dh, 8
mov dl, 3
mov cl, 2
call show_str ;IP入栈

mov ax, 4c00h
int 21h

show_str:
;把需要用到的寄存器入栈保护
push ax
push bx
push si
push es


;计算起始偏移地址
mov al, 160 ;行地址
dec dh
mul dh
mov bx, ax

mov al, 2 ;列地址
dec dl
mul dl
add bx, ax ;偏移地址

mov ax, 0b800h;
mov es, ax ;基址地址

mov al, cl
mov si, 0

;循环执行mov指令
s: mov cl, ds:[si] ;判断是否结束循环
jcxz ok
mov es:[bx], cl
mov es:[bx+1], al

inc si
add bx, 2
jmp short s

ok:
pop es
pop si
pop bx
pop ax
ret ;IP出栈

dtoc:
; 寄存器入栈保护
push si
push bx
push cx
push dx
; 计算十进制数字每位的值
mov si, 0
mov bx, 10d


s1: mov dx, 0
div bx
mov cx, ax
add dx, 30H ; 转换ASCII码

push dx
inc si
jcxz over
jmp short s1


over: mov cx, si
mov si, 0

s2: pop dx
mov ds:[si], dx ; 修改到data字段
inc si
loop s2

pop dx
pop cx
pop bx
pop si
ret

code ends
end start

标志寄存器

t837KH.png
flag和其他寄存器不一样,其他寄存器是用来存放数据的,都是整个寄存器具有一个含义;
而flag寄存器是按位起作用的,也就是说,它的每一位都有专门的含义,记录特定的信息。

ZF标志(第6位)–零标志位

记录相关指令执行后,其结果是否为0.

  1. 结果为0:zf=1;
  2. 结果不为0:zf=0。

注意是与结果相反的

PF标志(第2位)–奇偶标志位

它记录相关指令执行后,其结果的所有bit位中1的个数是否为偶数。

  1. 1的个数为偶数:pf=1,
  2. 奇数:pf=0。

SF标志(第7位)–符号标志位

  1. 结果为负,SF=1;
  2. 结果为正,SF=0。

通常用补码来表示有符号数据。
因此,对于一个二进制数据,计算机在既把它当做有符号数运算也进行无符号数运算,同时提供两种结果给程序选择。

CF标志(第0位)–进位/借位标志位

记录最高有效位向更高有效位的进位/借位
t8Nvin.png

  1. 有进位/借位:CF=1,
  2. 无进位/借位:CF=0。

OF标志(第11位)–溢出标志位

  1. 有溢出:OF=1,
  2. 无溢出:OF=0。
    CF和OF的区别:
    CF是对无符号数运算有意义的标志位;
    OF是对有符号数运算有意义的标志位。

adc指令

adc是带进位加法指令,它利用了CF位上记录的进位值。

adc obj1,obj2
obj1 = obj1+obj2+CF

基础知识

寄存器

寄存器(内存访问)

第一个程序

[BX]和loop指令

包含多个段的程序

更灵活的定位内存地址的方法

数据处理的两个基本问题

转移指令的原理