汇编学习4
前言
通过写1+2+3+…+100 的程序来认识一种新的数据结构-栈
栈
什么是栈
栈是一种特殊的数据结构,数据的存储只在一端进行,满足后进先出的特点。
和代码段 数据段 附加段一样,栈也被定义成一个内存段,叫做栈段,由段寄存器SS指向。
定义栈
定义栈需要两个连续的步骤,即初始化段寄存器SS和栈指针SP的内容。
关于栈的指令
push 和 pop
push命令是压入栈,push指令的操作数 可以是16位的寄存器或者内存单元,比如 push ax 或者
push word [label_a],就8086处理器来说,只能压入一个字,但其后的32位和64位 可以压入字、双字、四字。
push指令不影响标志位,push是由高地址向低地址压栈,而代码段在处理器上执行的时候,是从低地址向高地址推进:
push指令执行的时候,会将SP寄存器的内容减去2(16位寄存器),然后将SS寄存器的内容左移4位,然后加上SP的,得到实际内存地址的,然后把数据放过去。以后每次压栈的时候,SP都要减去2
pop指令和push指令一样,操作数是16位寄存器或内存单元
pop指令执行的时候,是直接将SS:SP对应的物理地址的内容弹出去,然后将SP的内容+2(16位寄存器)
进一步认识栈
1.push指令执行后,压入到栈中的仅仅只是该寄存器或者内存单元中的数值
2.栈在本质上也只是普通的内存区域
push ax 命令等价于 :
sub sp,2
mov bx,sp
mov [ss:bx],ax
3.注意栈平衡
4.编写程序前,必须充分估计栈所用的内存空间,以防止破坏有用的数据
8086处理器的寻址方式
什么是寻址方式
寻址方式简单来说,就是如何找到要操作的数据,以及如何找到存放操作结果的地方
寄存器寻址
指令执行的时候,操作数位于寄存器里面 。比如:
mov ax,cx
立即寻址
立即寻址又叫做立即数寻址,指令的操作数是一个立即数,比如:
add bx,0xf000
内存寻址
1.直接寻址
mov ax,[0x5c0f]
2.基址寻址
就是在指令的地址部分,使用基址寄存器BX或者BP来提供偏移地址
mov [bx] , dx
3.变址寻址
变址寻址类似于基址寻址,不同之处在于变址地址使用的是SI和DI(也称为索引寄存器),比如:
mov [si] , dx
还允许带一个偏移量:
mov [si+0x100],al
4.基址变址
操作数可以是一个基址寄存器(BX或者BP),外加一个变址寄存器(SI或者DI)比如:
mov ax,[bx+si]
代码展示
1 ;代码清单7-1
2 ;文件名:c07_mbr.asm
3 ;文件说明:硬盘主引导扇区代码
4 ;创建日期:2011-4-13 18:02
56 jmp near start
78 message db ‘1+2+3+…+100=’
9
10 start:
11 mov ax,0x7c0 ;设置数据段的段基地址
12 mov ds,ax
13
14 mov ax,0xb800 ;设置附加段基址到显示缓冲区
15 mov es,ax
16
17 ;以下显示字符串
18 mov si,message
19 mov di,0
20 mov cx,start-message
21 @g:
22 mov al,[si]
23 mov [es:di],al
24 inc di
25 mov byte [es:di],0x07
26 inc di
27 inc si
28 loop @g
29
30 ;以下计算1到100的和
31 xor ax,ax
32 mov cx,1
33 @f:
34 add ax,cx
35 inc cx
36 cmp cx,100
37 jle @f
38
39 ;以下计算累加和的每个数位
40 xor cx,cx ;设置堆栈段的段基地址
41 mov ss,cx
42 mov sp,cx
43
44 mov bx,10
45 xor cx,cx
46 @d:
47 inc cx
48 xor dx,dx
49 div bx
50 or dl,0x30
51 push dx
52 cmp ax,0
53 jne @d
54
55 ;以下显示各个数位
56 @a:
57 pop dx
58 mov [es:di],dl
59 inc di
60 mov byte [es:di],0x07
61 inc di
62 loop @a
63
64 jmp near $
65
66
67 times 510-($) db 0
68 db 0x55,0xaa