栈指令及寻址方式

栈指令及寻址方式

栈指令:

寄存器ss内存放着栈段地址,寄存器sp中保存着相对栈段寄存器ss的偏移地址

1
push 寄存器/内存
  1. sp = (sp - 操作数的大小) ,在16位8086中压栈出栈必须是一个字
  2. 段寄存器ss左移4位,加上sp的偏移地址,生成物理地址
  3. 将操作数写入上述地址中
1
pop  寄存器/内存
  1. 段寄存器ss左移4位,加上sp里的偏移地址,生成物理地址
  2. 从上述地址处取得数据,存入由操作数体统的目标位置处
  3. sp = sp + 2

逻辑指令

1
2
or 寄存器/内存 , 寄存器/内存/立即数
and 寄存器/内存 , 寄存器/内存/立即数

在执行l逻辑指令后:

OF = 0 CF = 0

SF ZF PF依据计算结果而定,AF的状态未定义

从1加到100并显示结果

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
;从1加到100并显示累加结果
jmp near start

message db '1+2+3+...+100='

start:
mov ax,0x7c0 ;设置数据段的段基地址
mov ds,ax

mov ax,0xb800 ;设置附加段基址到显示缓冲区
mov es,ax

;以下显示字符串
mov si,message
mov di,0
mov cx,start-message
@g:
mov al,[si]
mov [es:di],al
inc di
mov byte [es:di],0x07
inc di
inc si
loop @g

;以下计算1到100的和
xor ax,ax
mov cx,1
@f:
add ax,cx
inc cx
cmp cx,100
jle @f

;以下计算累加和的每个数位
xor cx,cx ;设置堆栈段的段基地址
mov ss,cx
mov sp,cx

mov bx,10
xor cx,cx
@d:
inc cx
xor dx,dx
div bx
or dl,0x30
push dx
cmp ax,0
jne @d

;以下显示各个数位
@a:
pop dx
mov [es:di],dl
inc di
mov byte [es:di],0x07
inc di
loop @a

jmp near $

times 510-($-$$) db 0
db 0x55,0xaa

基址寻址

基址寄存器 bx bp

1
2
mov dx , [bp+2];ss为段寄存器
mov dx , [bx+2];bs为栈寄存器

不需要使用段超越前缀ss,当使用基址寄存器bp进行寻址时,默认将寄存器ss中内存作为段寄存器

变址寻址

变址寄存器/索引寄存器 si di

1
2
3
mov [si+0x10] , dx
add ax , [di]
xor word [si] , 0x800

当指令中使用了变址寄存器并且没有使用段超越前缀,默认以bx中作为段地址

基址变址寻址

当使用基址寄存器bs时,默认使用段寄存器bx作为段地址

1
2
3
4
[bx + si]
[bx + di]
[bx + si + 偏移量]
[bx + di + 偏移量]

当使用基址寄存器bp时,默认使用段寄存器ss作为段地址

1
2
3
4
[bp + si]
[bp + di]
[bp + si + 偏移量]
[bp + di + 偏移量]

就地反转字符串内容

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
    jmp start;

string db 'abcdefghigklmnopqrstuvwxyz'

start:
mov ax , 0x7c0;
mov ds , ax;

mov bx , string;
mov si , 0;
mov di , start - string - 1;

rever:
mov ah , [bx + si];
mov al , [bx + di];
mov [bx + si] , al;
mov [bx + di] , ah;
inc si;
dec di;
cmp si , di;
jl rever;

jmp $

times 510 - ($-$$) db 0;
db 0x55 , 0xaa;