x86汇编语言学习:第七章 比高斯更快的计算

本章目标:

  1. 学习栈,了解处理器为了访问栈提供了怎样的支持
  2. 总结INTEL8086处理器的寻址方式
  3. 学习新的指令,or、and、push和pop
  4. 学习bochs调试程序时查看栈的方法

7.2 代码清单

asm-7-1.pdf

7.3 显示字符串

解读10-28行代码,即显示message字符串的功能

7.4 1到100的累计和

解读31到37行的代码,即通过CX和jns指令来循环执行,获取累计和

7.5 累加和各个数位的分解和显示

7.5.1 栈和栈段的初始化
  • 栈也是一个内存段,叫栈段(Stack Segment),由寄存器SS指向
  • 规划内存布局,同时将寄存器SS和栈指针SP置0

7.5.2 or,and,push指令
  • or指令,执行“或”操作,结果存于目的操作数中
  • and指令,执行“与”操作,结果存于目的操作数中
  • push指令,将寄存器或者内存地址的内容压入栈。在16位处理器上,push指令的操作数可以是16位的寄存器和内存单元
  • 例子: ``` push ax push word [label_a]

push al     ;非法指令,16位处理器,只能压入字


* 在执行push指令的时候,首先将栈指针寄存器SP的内容减去操作数的长度(以字节为单位的长度,在16位处理器上是2);然后将要压入栈的数据存放到逻辑地址SS:SP所指向的内存位置。由于SP初始化的时候为0,减去之后,SS:SP指向0xFFFE;此时,栈的执行是从高地址往低地址,而代码段CS的执行从低地址向高地址移动,这样就解决了栈段和代码段分离的问题。

<img src="https://github.com/firstmoonlight/MarkdownImages/blob/main/x86_assembly_nasm/Image7.png?raw=true" width="70%">

##### 7.5.3 pop指令
* pop指令,弹栈功能。将逻辑地址SS:SP处的一个字弹出到寄存器或内存位置中,然后将SP的内容加上操作数的字长(2)
* 例子:

pop ax pop word [lable_a]


##### 7.5.4 进一步认识栈
* push指令的详细流程

;push ax 可以用以下指令取代 sub sp, 2 mov bx, sp mov [ss:bx], ax

* pop指令的详细流程

; pop ax 可以用以下指令取代 mov bx, sp mov ax, [ss:bx] add sp, 2

* 使用栈的注意事项
1. 注意保持栈的平衡
1. 充分估计栈的空间,防止破坏有用的数据
1. 尽管不能完全阻止程序中的错误,但是通过将栈定义到一个单独的64KB段,可以使错误仅局限于栈

#### 7.6 程序的编译和运行

#### 7.7 8086处理器的寻址方式
寻址方式:即处理器如何找到被操作的数,以及如何找到存放数据的地方
##### 7.7.1 寄存器寻址
从寄存器取得操作的数

mov ax, cx add bx, 0xf000 inc dx


##### 7.7.2 立即寻址
指令的操作数是一个立即数

add bx, 0xf000 mov dx, lable_a


##### 7.7.3 内存寻址
###### 1、直接寻址
所谓直接寻址,即使用该寻址方式的操作数是一个偏移地址,而且给出了改偏移地址的具体数值

mov ax, [0x5c0f] mov word [0x0230], 0x5000 xor byte [es:lable_b], 0x05    ;标号是数值的等价形式


###### 2、基址寻址
所谓基址寻址,即在指令的地址部分使用基址寄存器BX或BP来提供偏移地址,例如:
* BX作为基址寄存器

mov [bx], dx add byte [bx], 0x55

好处是,可以用来进行批量加一的任务

buffer dw 0x20, 0x100, 0x0f, 0x300, 0xff00 mov bx, buffer mov cx, 4 lpinc: inc word [bx] add dx, 2 loop lpinc

* BP作为基址寄存器

mov ax, [bp] ;将SS:BP处的一个字传送到寄存器AX中

使用BP的作用是为了能够随意访问栈中的内容。一个应用就是函数调用时,访问那些被压在栈底的参数

###### 3、变址寻址
类似于基址寻址,唯一不同之处在于,这种方式使用的是变址寄存器(或称索引寄存器)SI和DI

mov [si], dx add ax, [di] xor word [si], 0x8000 ;处理器会访问由段寄存器DS指向的数据段,偏移地址由寄存器SI和DI提供


###### 4、基址变址寻址

mov ax, [bx+si] add word [bx+di], 0x3000 ```

Share: X (Twitter) Facebook LinkedIn