汇编语言递归法求阶乘
Posted 九死九歌
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了汇编语言递归法求阶乘相关的知识,希望对你有一定的参考价值。
众所周知,c语言一上来就给程序员分配好了堆栈,而在汇编语言中,内存分配却要程序员自己去解决,那就更不用说函数了,汇编语言无法实现函数调用。
但我们可以利用栈段来模拟函数的调用,我们可以划分一个十六字节的栈段来做为方法栈,利用call和ret指令实现函数调用功能。
代码如下:
assume cs : code, ds : data, ss : stack
data segment
db 6
data ends
stack segment
db 10H dup(0)
stack ends
code segment
start: ; 作用相当于主函数
mov ax, data
mov ds, ax
mov ax, stack
mov ss, ax
mov sp, 10H
mov di, 0 ; di作为返回值
mov si, ds:[0] ; si作为参数
push si
call fact ; 参数已传递,调用函数
pop si
mov ds:[0], di
mov ax, 4c00H
int 21H
fact: ; 求阶乘的递归函数实现
cmp si, 0
je e
push si ; 将当前的参数入方法栈
dec si ; 传参si-1
call fact ; 调用函数
pop si ; 函数调用完毕,弹栈
mov ax, si
mul di
mov di, ax
ret ; 返回运算结果
e:
mov di, 1 ; 若传参0,返回1
ret
code ends
end start
也可以把注释写成c语言。
assume cs : code, ds : data, ss : stack
data segment
db 6 ;int ds[] = {6};
data ends
stack segment
db 10H dup(0)
stack ends
code segment
start: ;int main () {
mov ax, data
mov ds, ax
mov ax, stack
mov ss, ax
mov sp, 10H
mov di, 0
mov si, ds:[0]
push si
call fact ; ds[0] = fact(si);
pop si
mov ds:[0], di
mov ax, 4c00H ; return 0;
int 21H ;}
fact: ;int fact (int n) {
; register int di;
cmp si, 0
je e ; if (si != 0) {
push si
dec si ; di = fact(si - 1);
call fact ;
pop si
mov ax, si ; di = si * di;
mul di
mov di, ax
ret ; return di;
e: ; } else {
mov di, 1 ; return 1
ret ; }
;}
code ends
end start
由此可见,在函数A中调用函数B时要将函数A的参数及局部变量入方法栈,调用结束后弹方法栈。
c语言版本的递归求阶乘是这样子的:
int fact(int n) {
if (n == 0) return 1;
return n * fact(n - 1);
}
int main () {
int n = 6;
n = fact(n);
}
一共书写了8行,而x86汇编却写了足足39行(不算只为代码美观性的无意义的回车换行符)。可见高级语言对比汇编语言是真的高效。
但是汇编语言对寄存器不透明,以及面向硬件等特性是高级语言所无法具备的。
现实生活中做开发肯定是使用高级语言做算法了。但是使用汇编语言可以对计算机底层做出更全面更深入的了解。
以上是关于汇编语言递归法求阶乘的主要内容,如果未能解决你的问题,请参考以下文章