要点一:
有许多计算机系统都会做一些限制,要求某种类型的对象的地址必须是某个值k的倍数。为什么需要对齐?因为这种对齐限制简化了处理器和存储器系统之间接口的硬件设计,比如一个处理器总是从存储器中取8个字节,那么地址必须是8的倍数。
例如,在汇编中会有这么个命令:
.align 4
这个命令就表示后面的数据会以4的倍数的地址处开始。
要点二:
浮点单元包括8个浮点寄存器,但是和普通寄存器不一样,这些寄存器是被当成一个浅栈来使用的。它们的标识为:%st(0)、%st(1)......值到%(7)。其中0当作栈顶,超过八个栈底的值就会消失。
大多数算术指令不会直接引用寄存器,而是从栈中弹出它们的源操作数,计算结果,再将结果压入栈中。
要点三:
栈的表达式求值,是浮点寄存器作为栈的一个比较经典的应用。在了解求值之前,需要先了解几个命令:
指令 | 效果 |
load S | 将s处的值压入栈中 |
storep D | 弹出栈顶元素并存储在D处 |
neg | 栈顶元素取负 |
addp | 弹出两个栈顶元素:压入它们的和 |
subp | 弹出两个栈顶元素:压入它们的差 |
multp | 弹出两个栈顶元素:压入它们的积 |
divp | 弹出两个栈顶元素:压入它们的比值 |
知道了命令,接下来就利用一个例子:x=(a-b)/(-b+c),那么栈的情况就是:
↓
c | %st(1) | |
load b | b | %st(0) |
↓
c | %st(1) | |
neg | -b | %st(0) |
↓
↓
-b+c | %st(1) | |
load b | b | %st(0) |
↓
-b+c | %st(2) | |
b | %st(1) | |
load a | a | %st(0) |
↓
-b+c | %st(1) | |
subp | a-b | %st(0) |
↓
storep x
question1:
栈1:
栈2: