程序机器级表示 3.压栈出栈与算术逻辑操作

栈是一个典型的数据结构类型,在此对栈的思想不再赘述,这里讲一下栈的汇编实现。

栈遵循后进先出的原则,通过push将数据压栈,通过pop删除数据。栈底的地址为最大的。

对应命令就是

pushq S,将四字压入栈中

popq  D,将四字弹出栈

push等价于:

sub $8,%rsp

movq %rbp,(%rsp)

pop等价于:

movq (%rsp), %rax

add $8, %rsp


加载有效地址leaq

加载有效地址(load effective address) leaq的指令形式是从内存读数据到寄存器。

下面以例子说明

long scale(long x, long y, long z)

{

long t=x+4*y+12*z;

return t;

}

其对应的汇编为

scale:

  leaq (%rdi,%rsi,4), %rax    #x+4*y

  leaq (%rdx,%rdx,2), %rdx  #z+2*z=3*z

  leaq (%rax,%rdx,4), %rax  #(x+4*y) + 4*(3*z)=x+4*y+12*z

  ret 


一元操作数

INC  加一

DEC 减一

NEG 取负

NOT 取补


二元操作数

ADD S,D 加

SUB S,D 减

IMUL S,D 乘

XOR S,D 异或

OR S,D 或

AND S,D 与


移位操作,先给出移位量,第二项给出要移位的数。移位量可以是一个立即数,或者将移位量存放在单字节寄存器%cl中。

SAL k, D 左移

SHL k,D 左移,等同于SAL

SAR k,D 算术右移

SHR k,D 逻辑右移


乘法操作

imulq双操作数 即从两个64位操作数产生一个64位乘积

补码乘法:要求有一个参数必须在寄存器%rax中,另一个作为指令的源操作数给出。

乘积的高64位%rdx,低64位%rax中。

例子

C语言:

void store_uprod(uint128_t *dest, uint64_t x, uint64_t y)

{

*dest=x*(uint128_t)y;

}

汇编:

store_uprod:

movq %rsi, %rax

mulq %rdx

movq %rax, (%rdi)

movq %rdx, 8(%rdi)

ret


除法

C语言:

void remdiv(long x, long y, long *qp, long *rp)

{

long q=x/y;

long r= x%y;

*qp=q;

*rp=r;

}

汇编:

remdiv:

movq %rdx, %r8

movq %rdi, %rax #低八位复制

cqto      #自动按符号位补全高八位

idivq %rsi #除法操作

movq %rax, (%r8) #存商

movq %rdx, (%rcx)#存余数

ret

无符号数除法使用divq指令。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值