博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
汇编语言第三章总结
阅读量:5124 次
发布时间:2019-06-13

本文共 2551 字,大约阅读时间需要 8 分钟。

在csapp中的新理解:

 (1)栈向下增长,栈顶元素的地址是所有栈中元素地址中最低的

(2)因为栈和程序代码以及其他形式的程序数据都是放在同一内存中,所以程序可以用标准内存寻址方法访问栈内的任意位置

(3)加载有效地址(load effective address)指令leap实际上是movq指令的变形,它的指令形式是从内存读数据到寄存器,但实际上它根本就没有引用内存。

         例:leap (%rdx),%rax

         它的第一个操作数看上去是一个内存引用,但该指令并不是从指定位置读入数据,而是将有效地址写入到目的操作数。这条指令可以为后面的内存引用产生指针。目的操作数必须是一个寄存器。

书上内容的总结:

3.1 内存中字的存储

  • 字单元:即存放一个字型数据(16位)的内存单元,由两个地址连续的内存单元组成。
  • 小端法:高地址内存单元中存放字型数据的高位字节,低地址内存单元中存放字型数据的地位字节
  • 低地址的内存单元作为字数据地址
  • N地址字单元:起始地址为N的字单元
  • 任何两个地址连续的内存单元,N号单元和N+1号单元,可以将他看成两个内存单元,也可看成一个地址为N的字单元的高位字节单元和地位字节单元

3.2 DS和[address]

  • DS段寄存器:用来存放要访问数据的段地址
  • ds的赋值:(8086不支持将数据直接送入段寄存器的操作,只好用一个寄存器来进行中转)
mov bx,1000Hmov ds,bx
  • [...]表示一个内存单元,[...]中的数字表示内存单元的偏移地址
  • 8086CPU自动取ds中的数据为内存单元的段地址

3.3 字的传送

  • 8086是16位结构,有16根数据线,可以一次性传送16位的数据,即可以一次性传送一个字
  • 传送字型数据的实例:
mov ax,1000hmov ds,ax        ;改变ds的值mov ax,[0]       ;将地址为10000的字数据送入axmov bx,[2]       ;将地址为10002的字数据送入bxmov cx,[4]       ;将地址为10004的字数据送入cx

3.4 mov、add、sub指令

  • mov、add、sub指令的总结:

   

  • 注意事项:

1)指令中两个操作数的长度要一样(mov ax,cl  mov al,300 这都是错误的)

(2)关于立即数:不能作为第一个操作数(目的操作数);在完整的汇编程序中,作第二个操作数(源操作数)时,若最高位是十六进制的a~f,前面要加零

(3)两个内存单元之间不能直接传送数据

(4)不能使用mov指令直接改变cs和ip的值

(5)关于段寄存器:两个段寄存器之间不能直接传送;不能把常数送入段寄存器

3.5 数据段

  • 可以将一组长度为N(N<=64KB)、地址连续,起始地址为16的倍数的内存单元当作专门存储数据的内存空间——定义数据段
  • 用ds存放数据段的段地址

3.6 栈

  • 后进先出(LIFO):最后进入这个空间的数据,最先出去
  • 两个基本操作:入栈(PUSH)和出栈(POP)
push ax  ;表示将寄存器ax中的数据送入栈中pop ax   ;表示从栈顶取出数据送ax

(push 内存单元和pop 内存单元  实际上实现了从内存单元到内存单元的传送)

  • 注意事项:

(1)操作对象不能是常数

(2)pop 段寄存器 中,段寄存器不能是CS和SS

(3)出栈和入栈以字为单位

3.7 CPU提供的栈机制

  • 段寄存器SS:栈段段寄存器    寄存器SP:栈指针寄存器
  • 栈顶的段地址存放在SS中,偏移地址存放在SP中
  • 任意时刻,SS:SP指向栈顶元素
  • 栈顶的物理地址:SS*16+SP   
  • push的执行:(入栈时,栈顶从高地址向低地址方向增长

(1)先SP=SP-2   (2)再将ax中的内容送入SS:SP指向的内存单元处

  • pop的执行:

(1)先将SS:SP指向的内存单元处的数据送入ax中  (2)再SP=SP+2

  • 栈为空时,就相当于栈中唯一的元素出栈,此时栈顶指向的单元的偏移地址为栈最底部的字单元的偏移地址+2
  • pop操作前的栈顶元素,在pop以后,依然存在,但是它已不在栈中,当再次执行push时,它将被覆盖

3.8 栈顶超界问题

  • 当栈空时,再使用pop出栈
  • 当栈满时,再使用push入栈
  • 有可能取到栈以外未知的值,若栈段的大小为64KB,会使栈指针重新指向最后进栈的元素的地址,重新又执行指令
  • 栈空间的大小我们要自己管理

3.9 栈段

  • 一个栈段最大可以设为64KB

(push,pop等栈操作,修改的只是SP,也就是说,栈顶的变化范围最大为:0~FFFFH)

  • 初始化栈段:
;将10000h~1000fh这段空间当作栈mov ax,1000hmov ss,ax          ;设置栈的段地址,ss=1000hmov sp,0010h    ;设置栈顶的偏移地址,因栈为空,所以sp=0010h

3.10 利用栈保护现场和实现数据交换

  • 保护现场:
mov ax,1000hmov ss,axmov sp,0010h   ;初始化栈顶mov ax,001Ahmov bx,001Bhpush axpush bxpop bx   ;从栈中恢复ax,bx原来的值pop ax
  • 实现数据交换:
;初始化的栈段和ax,bx的值的代码同上push axpush bxpop ax   ;当前栈顶是bx中原来的数据:001Bh,此时使ax=001Bhpop bx   ;此时栈顶使ax中原来的数据:001Ah,此时使bx=001Ah

课后思考:

思考了一下,如何使用栈操作实现字节数据的交换?

我认为首先要把字节数据扩展成字数据,再进行栈操作实现字节数据的交换。

在csapp中介绍了一系列零扩展和符号扩展的指令(AT&T汇编),其中,movzbw则是将做了零扩展的字节传送到字,也许可以如下进行交换:

movzbw %al,%eax  ;将al中的字节数据做零扩展送到ax中movzbw %bl,%ebxpushl %eaxpushl %ebxpopl %eaxpopl %ebx

 

转载于:https://www.cnblogs.com/kwcymino/p/9892538.html

你可能感兴趣的文章
OO5~7次作业总结
查看>>
使用Xshell密钥认证机制远程登录Linux
查看>>
OpenCV之响应鼠标(三):响应鼠标信息
查看>>
Android 画图之 Matrix(一)
查看>>
List<T>列表通用过滤模块设计
查看>>
【模板】最小生成树
查看>>
设计模式之结构型模式
查看>>
poj2569
查看>>
使用pygal_maps_world.i18n中数据画各大洲地图
查看>>
sql server必知多种日期函数时间格式转换
查看>>
jQuery EasyUI 的下拉选择combobox后台动态赋值
查看>>
timeline时间轴进度“群英荟萃”
查看>>
python if else elif statement
查看>>
网络编程
查看>>
文本隐藏(图片代替文字)
查看>>
java面试题
查看>>
提高码力专题(未完待续)
查看>>
pair的例子
查看>>
前端框架性能对比
查看>>
@property中 retain 详解
查看>>