x86汇编学习历程7----从1加到100并显示(引入栈)
Posted 4nc414g0n
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了x86汇编学习历程7----从1加到100并显示(引入栈)相关的知识,希望对你有一定的参考价值。
新知识点
栈
SS:栈段段寄存器
SP (stack pointer):栈指针寄存器,提供访问栈段的偏移地址
SP总指向最后一个压入堆栈的数据所在的数据单元——栈顶
注意:
1)不同于代码段和数据段,栈段的扩展推进方向是向下的,从高地址向低地址推进
2)由于栈段和代码段在同一块区域,为防止破坏有用数据,要充分估计需要的栈空间
压栈 push(在8086处理器push操作的只能是一个字 也就是16位):
执行过程:
1)SP-操作数的大小(字节数)存入到SP中
2)段寄存器SS左移4位,加上SP里的偏移地址,生成物理地址
3)将操作数写入上述地址
push r/m
例如:
push dx
push word [0x2002];//从0x2002取出一个字压入栈
----------------------------------------------------------------------------
出栈 pop(在8086处理器pop操作的只能是一个字 也就是16位):
执行过程:
1)段寄存器SS左移4位,加上SP里的偏移地址,生成物理地址
2)从上述地址取得数据,存入由操作数提供的目标位置处
3)SP<-SP-2
pop r/m
例如:
pop ax
pop word [0x08] ;//从栈中取出一个字放到0x08处
图例 (pop相反同理) :
利用push和pop可以代替一些冗余的代码
例如:
sub sp,2
mov bx,sp
mov [ss:bx],ax
等效于
push ax
------------------------------------------------------------------------------
mov bx,sp
mov ax,[ss:bx]
add sp,2
等效于
pop ax
逻辑与&或
与and:
and r/m,r/m/imm (两个操作数长度必须一致)
或or:
or r/m,r/m/imm (两个操作数长度必须一致)
由于:
我们在除法操作中余数在dl中,且余数总是很小,只占据低四位,
所以dl的高四位一定为0
---------------------------------------------------------------------------
dl: 0000 ????
或操作
0x30: 0011 0000
等于 0011 ????
即:or dl,0x30 等效于 add dl,0x30
----------------------------------------------------------------------------
(注意:此只是特例,并不是所有都适用)
对标志位影响:
OF=0,CF=0
SF,ZF,PF依计算结果而定
AF的状态未定义
代码如下
;//从1加到100显示累加结果
jmp start
message db '1+2+3+4+...+100=';//等同于'1','+','2','+','3','+','4','+','.','.','.','+','100','='
start:
mov ax,0x7c0
mov ds,ax
mov ax,0xb800
mov es,ax
mov si,message;//字符串首地址传送到si
mov di,0
mov cx,start-message;//字符串的长度传到cx
showmsg:
mov al,[si]
mov [es:di],al
inc di
mov byte [es:di],0x07;//颜色属性
inc di
inc si
loop showmsg;//循环
;//以下计算1到100的和
xor ax,ax;//ax用于存放累加和(ax可容纳数最多为65535)累加和小于此数可放心使用
mov cx,1
summate:
add ax,cx
inc cx;//cx加1
cmp cx,100;//cx和100比较
jle summate;//jle(jump if less or equal)如果cx小于等于100则跳转到summate
;//以下分解累加和的每个数位
xor cx,cx;//设置栈段的段基地址
mov ss,cx
mov sp,cx
mov bx,10
xor cx,cx
decompo:
inc cx
xor dx,dx
div bx
add dl,0x30
push dx
cmp ax,0
jne decompo
;//以下显示各个数位
shownnum:
pop dx
mov [es:di],dl
inc di
mov byte [es:di],0x07
inc di
loop shownnum
jmp $
times 510-($-$$) db 0
db 0x55,0xaa
bochs调试
设置断点到push处 执行
由于最初SS和SP的偏移地址都是0000,push后SP-2会变为FFFE
如下图所示:
最后显示出结果
以上是关于x86汇编学习历程7----从1加到100并显示(引入栈)的主要内容,如果未能解决你的问题,请参考以下文章
x86汇编学习历程6----负数在计算机中的表示和应用方法(附FLAGS拓展和cmp及条件转移指令)