编程范式之汇编语言

       学习,了解汇编语言的工作机制和编写流程,有助于我们对程序的执行有一个比较清晰的认识。

       主要的过程就是寻找能够存放数据的内存地址,将数据存放至这个地址之上,取出内存中数据至寄存器,寄存器经过计算后写回内存。

       需要清楚的是,调用者知道被调用的函数有几个参数,调用者分配内存空间,而只有被调用的函数知道其内部有几个局部变量,函数分配内存空间。

       还需要清楚的是,局部变量的入栈顺序依次为由高到低,而函数参数在内存中的分配(第一个参数总是在最低地址处),即由低至高分配,这样做的好处是,当参数为变长参数时,其栈指针总能指向函数的第一个参数。

       以下面的代码为例,我们写出相应的汇编语句,注意,在这里我们假设每一条汇编指令的大小均为4个字节。最终,根据指令集,将汇编语句翻译成计算机能够识别的机器码。

int main() {
	int i = 4;
	foo(i, &i);
	return 0;
}

 

void foo(int bar, int *baz) {
	char snink[4];
	short * why;
	why = (short *) (snink + 2);
	*why = 50;
}

 

SP: STACK POINTER

 

SP = SP - 4;       // 内存是 由高向低进行扩展的,故需要减去4,来存放int 4,(设定能够存放4 的内存位置)

M[SP] = 4;          // 将其内存位置赋值

 

SP = SP - 8;       // i, &i, 一共8个字节

R1 = M[SP + 8];  // 取出i 值

R2 = SP + 8;       // 取出i 地址

M[SP] = R1;        // 给相应的内存赋值

M[SP + 4] = R2;

 

CALL <foo>;

SP = SP + 8;   // 栈指针返回

RV = 0;   // 返回0

 

<foo> : SP = SP - 8; // 两个局部变量

R1 = SP + 6;     // char char char char 4bytes   short *  4bytes     snink + 2 =  short * + 2 个char 的位置(6)                    

M[SP] = R1;       // why 的地址改变

 

R1 = M[SP];       // 取地址     

M[R1] = .2  50;    // 解引用  .2表示2个字节(short), 相应的地址 赋相应的值

SP = SP + 8;     // 回收局部变量

RET;   // 返回

 

附:一个递归函数的递归写法:

int fact(int a) {
	if (n == 0) return 1;
	return n * fact(n - 1);
}

 

SP 的位置为当前函数在栈中的位置,取得参数故需向高地址寻找,(总能从第一个参数开始寻找)

<fact>:

R1 = M[SP + 4];

BNE R1,0, PC + 12;   //  12 跳跃三条汇编指令(每条汇编指令假设为4个字节)

RV = 1;

RET;

R1 = M[SP + 4];

R1 = R1 - 1;

SP = SP - 4;

M[SP] = R1;

CALL <fact>;    // 使得SP向下延伸4个字节,将这个指令存储至saved PC中

SP = SP + 4;

R1 = M[SP + 4];

RV = RV * R1;

RET;

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值