标签:指针 如何 数据线 物理地址 一个 交换 lifo style 方法
(1)栈向下增长,栈顶元素的地址是所有栈中元素地址中最低的
(2)因为栈和程序代码以及其他形式的程序数据都是放在同一内存中,所以程序可以用标准内存寻址方法访问栈内的任意位置
(3)加载有效地址(load effective address)指令leap实际上是movq指令的变形,它的指令形式是从内存读数据到寄存器,但实际上它根本就没有引用内存。
例:leap (%rdx),%rax
它的第一个操作数看上去是一个内存引用,但该指令并不是从指定位置读入数据,而是将有效地址写入到目的操作数。这条指令可以为后面的内存引用产生指针。目的操作数必须是一个寄存器。
3.1 内存中字的存储
3.2 DS和[address]
mov bx,1000H mov ds,bx
3.3 字的传送
mov ax,1000h mov ds,ax ;改变ds的值 mov ax,[0] ;将地址为10000的字数据送入ax mov bx,[2] ;将地址为10002的字数据送入bx mov cx,[4] ;将地址为10004的字数据送入cx
3.4 mov、add、sub指令
(1)指令中两个操作数的长度要一样(mov ax,cl mov al,300 这都是错误的)
(2)关于立即数:不能作为第一个操作数(目的操作数);在完整的汇编程序中,作第二个操作数(源操作数)时,若最高位是十六进制的a~f,前面要加零
(3)两个内存单元之间不能直接传送数据
(4)不能使用mov指令直接改变cs和ip的值
(5)关于段寄存器:两个段寄存器之间不能直接传送;不能把常数送入段寄存器
3.5 数据段
3.6 栈
push ax ;表示将寄存器ax中的数据送入栈中 pop ax ;表示从栈顶取出数据送ax
(push 内存单元和pop 内存单元 实际上实现了从内存单元到内存单元的传送)
(1)操作对象不能是常数
(2)pop 段寄存器 中,段寄存器不能是CS和SS
(3)出栈和入栈以字为单位
3.7 CPU提供的栈机制
(1)先SP=SP-2 (2)再将ax中的内容送入SS:SP指向的内存单元处
(1)先将SS:SP指向的内存单元处的数据送入ax中 (2)再SP=SP+2
3.8 栈顶超界问题
3.9 栈段
(push,pop等栈操作,修改的只是SP,也就是说,栈顶的变化范围最大为:0~FFFFH)
;将10000h~1000fh这段空间当作栈 mov ax,1000h mov ss,ax ;设置栈的段地址,ss=1000h mov sp,0010h ;设置栈顶的偏移地址,因栈为空,所以sp=0010h
3.10 利用栈保护现场和实现数据交换
mov ax,1000h mov ss,ax mov sp,0010h ;初始化栈顶 mov ax,001Ah mov bx,001Bh push ax push bx pop bx ;从栈中恢复ax,bx原来的值 pop ax
;初始化的栈段和ax,bx的值的代码同上 push ax push bx pop ax ;当前栈顶是bx中原来的数据:001Bh,此时使ax=001Bh pop bx ;此时栈顶使ax中原来的数据:001Ah,此时使bx=001Ah
思考了一下,如何使用栈操作实现字节数据的交换?
我认为首先要把字节数据扩展成字数据,再进行栈操作实现字节数据的交换。
在csapp中介绍了一系列零扩展和符号扩展的指令(AT&T汇编),其中,movzbw则是将做了零扩展的字节传送到字,也许可以如下进行交换:
movzbw %al,%eax ;将al中的字节数据做零扩展送到ax中 movzbw %bl,%ebx pushl %eax pushl %ebx popl %eax popl %ebx
标签:指针 如何 数据线 物理地址 一个 交换 lifo style 方法
原文地址:https://www.cnblogs.com/kwcymino/p/9892538.html