汇编语言学习——寄存器 2013-06-07 06:28:00 ## 通用寄存器 - 在进行数据传送或运算时,需注意指令的两个操作对象位数应当一致,如`mov ax, bx`,不能将al mov到ax中。 <!--more--> ## 物理地址 - 8086CPU有20位地址总线,可以传送20位的地址,到达1MB寻址能力。8086又是16位结构,在内部一次性处理、传输、暂存的地址为16位。 - 8086CPU采用2个16位地址合成的方法形成一个20位的物理地址。`物理地址=段地址*16 + 偏移地址`。 ## 段地址 - 段地址*16必然是16的倍数,所以一个段的起始地址也一定是16的倍数 - 偏移地址为16位,16位地址的寻址能力为64KB,所以一个段的长度最大为64KB。 ## 段寄存器——CS和IP - 8086CPU有4个段寄存器,其中CS用来存放*指令*的段地址。 - 任意时刻,CS:IP执行的内容当做指令来执行 - 通过`jmp`指令修改CS:IP,可以使用`jmp 段地址:偏移地址`同时修改CS和IP的内容,若仅修改IP的内容,则可以通过`jmp 某一合法寄存器`完成,如`jmp ax`会将ax中的值修改IP。 ## DS和[address] mov指令可以完成两种传送: 1. 将数据直接送入寄存器 2. 将一个寄存器中的内容送入另一个寄存器 3. 也可以将一个内存单元中的内容送入一个寄存器中 4. `[...]`表示一个内存单元,其中的内容表示内存单元的偏移地址 5. 8086CPU自动取DS中的数据作为内存单元的段地址 6. 8086CPU不支持将数据直接送入段寄存器(硬件设计原因) ``` mov bx, 1000H mov ds, bx mov al, [0] ``` 上面的指令将内存单元10000H(1000:0)中的数据读到al中。 **字在内存中的存储*** - 字在内存中存放需要2个连续地址的内存单元存放,字的低位字节在低地址单元中,高位字节存放在高位地址单元中。 - mov,add,sub是具有2个操作对象的指令,jmp是具有一个操作对象的指令。 ## CPU栈的机制 - 如今的CPU都有栈的设计 - 8086CPU的入栈和出栈操作都是以字为单位进行的,如:`push ax ; 将ax中的内容放入当前栈顶单元是上方`,`pop bx ; 从栈顶单元取出数据送入bx` - 任意时刻SS:SP指向栈顶元素 - 一个栈段的最大容量为64KB(栈通过SP寻址,所以栈顶的变化范围是0~FFFFH,最大能指向64KB) **push ax操作分析** 1. SP=SP-2,SS:SP只想当前栈顶前面的单元,以当前栈顶前面的单元为心的栈顶 2. 将ax中的内容送入SS:SP指向的内存单元,SS:SP此时指向新栈顶 如果将10000H~1000FH这段空间当做栈,初始状态栈是空的,此时SS=1000H,那么SP=? ![SP地址分析](/api/file/getImage?fileId=5ab5b929ba8bc2481f00007e) **栈顶越界问题** 编程时需要自己操心栈顶超界问题,需要根据可能使用到的最大的栈空间,来安排栈的大小,方式数据过大越界。 **push,pop指令** push和pop的操作对象可以是:寄存器,段寄存器,内存单元。如: ``` push ax push ds pop [2] ``` ## 段的综述 - 我们可以用一个段存放数据,将它定义为“数据段”,将它的段地址放在DS中,用mov,add,sub访问内存单元指令时,CPU就将我们定义在数据段中的内容当做数据来访问。 - 我们可以用一个段存放代码,将它定义为“代码段”,将它的段地址放在CS中,将段中的第一条指令的偏移地址放在IP中,这样CPU就将执行我们定义在代码段中的指令。 - 我们可以用一个段当做栈,将它定义为“栈段”,将栈顶单元的偏移地址放在SP中,这样CPU在需要进行栈操作的时候,比如执行push,pop指令等,就将我们定义的栈段当做栈空间来用。 ## 附,寄存器清零操作 比如将ax清零。可以使用`sub ax, ax`(机器码只占2个字节)或`mov ax, 0`(机器码占3个字节) 非特殊说明,均为原创,原创文章,未经允许谢绝转载。 原始链接:汇编语言学习——寄存器 赏 Prev Ghost博客坎坷安装过程 Next 汇编语言学习——基础知识