帮忙看下这个简单的汇编程序(函数返回值)
global mainfibo:
cmp eax, 1
je _get_out
cmp eax, 2
je _get_out
push ebx
push ecx
push edx
mov edx, eax
sub eax, 1
call fibo
mov ebx, eax
mov eax, edx
sub eax, 2
mov ecx, eax
mov eax, ebx
add eax, ecx
pop edx
pop ecx
pop ebx
_get_out:
mov eax, 1
ret
main:
mov eax, 7
call fibo
ret
如上一个简单的求Fibonoacci数的汇编程序段
为啥eax不需要压栈????不需要保存eax的状态吗?那为啥ebx、ecx、edx需要呢,有啥区别? ;递归调用的fibo函数,其中eax寄存器用来传递参数所以不用入栈保存
fibo:
;递归返回条件 eax = 1 或 eax = 2
cmp eax, 1
je _get_out
cmp eax, 2
je _get_out
push ebx
push ecx
push edx
;递归函数里用到了ebx,ecx,edx三个寄存器,所以这3个寄存器要入栈保存
mov edx, eax
sub eax, 1
call fibo
mov ebx, eax
mov eax, edx
sub eax, 2
mov ecx, eax
mov eax, ebx
add eax, ecx
pop edx
pop ecx
pop ebx
_get_out:
mov eax, 1
ret
main:
mov eax, 7
call fibo
ret
不过代码似乎有问题
斐波那契的递归写法
long fibo(long i)
{
if(i <= 2)
return 1;
else
returnfibo(i-1)+fibo(i-2);
}
xieglt 发表于 2020-10-13 17:06
不过代码似乎有问题
斐波那契的递归写法
谢谢回复。那么为啥eax就不用保存呢,在调用这个fibo函数之前,eax不也有值的吗?和ebx、ecx、edx有啥区别呢? xieglt 发表于 2020-10-13 17:06
不过代码似乎有问题
斐波那契的递归写法
代码不是我写的,是知乎上看到的 爷就是爷 发表于 2020-10-13 19:15
代码不是我写的,是知乎上看到的
详细注释了一下,能看懂吗
;递归调用的fibo函数,其中eax寄存器用来传递参数所以不用入栈保存
fibo:
;递归返回条件 eax = 1 或 eax = 2 这个返回条件可以写成 eax <= 2
;cmp eax, 1
;je _get_out
;cmp eax, 2
;je _get_out
cmpeax,2
jle_get_out
push ebx
push ecx
push edx
;递归函数里用到了ebx,ecx,edx三个寄存器,所以这3个寄存器要入栈保存
;用edx来保存eax的值
mov edx, eax
;eax - 1 ,并把eax作为参数递归调用 fibo ,相当于计算 fibo(i - 1)
sub eax, 1
call fibo
;返回值在eax中,取得返回值保存在ebx中
mov ebx, eax
;将之前保存在edx中的参数赋给 eax
mov eax, edx
;eax - 2,并把 eax 作为参数递归调用 fibo ,相当于计算 fibo(i-2)
sub eax, 2
;这里少了一句递归调用
call fibo
;返回值在eax 中,取得返回值并保存进 ecx,当然,这里纯属脱裤子放屁,直接写成 add eax,ebx 即可
mov ecx, eax
;取得之前计算的 fibo(i-1)
mov eax, ebx
;计算fibo(i-1) + fibo(i-2)
add eax, ecx
pop edx
pop ecx
pop ebx
;这里少了一个返回语句,不然返回值 eax 总是1
ret
_get_out:
mov eax, 1
ret
main:
;eax = 7 ,调用 fibo ,相当于 fibo(7)
mov eax, 7
call fibo
ret
为什么要在函数执行前入将各寄存器中的值入栈呢?是为了这个函数执行完后CPU能返回到函数执行前的环境,也就是先把原来寄存器中的值寄存在栈中,当当前程序执行完后CUP还要取回原来寄存器中的值,继续之前的工作。但是这里为什么没有把EAX的值入栈保存呢?EAX是累加器,主要用来传参的,这时候CPU认为它里面原来是什么不重要,所以没有将它的值入栈保存。简而言之,EAX可入栈也可不入栈,因为它不重要,所以没入栈。 兔子不说话 发表于 2020-10-15 16:18
为什么要在函数执行前入将各寄存器中的值入栈呢?是为了这个函数执行完后CPU能返回到函数执行前的环境,也 ...
是因为(E)AX比较特殊吗?eax和ebx、ecx一样在调用之前肯定也有数据,这里的数据是不重要的对吗? 是的 兔子不说话 发表于 2020-10-18 10:39
是的
eax、ebx不都是数据寄存器吗?
有啥不同,这样说CX还存放循环变量的值,不也可以随便放脏数据吗,反正都要被覆盖掉? 只是程序的编写者觉得这个寄存器中的数据不重要所以没有入栈,通常这样写也不会出什么大问题,在规范的汇编语言上所有寄存器的值都是应该在使用前入栈保存的。 兔子不说话 发表于 2020-10-18 19:38
只是程序的编写者觉得这个寄存器中的数据不重要所以没有入栈,通常这样写也不会出什么大问题,在规范的汇编 ...
你确定?are you sure? 嗯,最开始提出过类似的问题,当时那段程序是ECX没有入栈。 萌出血 发表于 2020-10-19 03:56
你确定?are you sure?
这些寄存器怎么用,书上只是提出了惯例,惯例是很多人一起写程序形成的,如果你知道了惯例,看别人写的程序时,就容易看懂些。
你完全可以自己改变这些寄存器的用法(特殊的除外),你想用它做什么就是什么?毕竟计算机并不知道什么是惯例。比如说,你一定要EBX做计次用,一定要用EDX做累加用,计算机也拿你没办法。
本程序EAX不需要入栈,是因为在作者的这个程序中,EAX可以不入栈。
入栈的都是为了在现在保存结果(入栈的主要用途),以备将来使用,这样可以节约寄存器。
为什么要节约寄存器,那是因为在远古时代(扯远了,其实就是计算机刚发明时)寄存器很珍贵,非常珍贵,必须节约、有效利用。所以一代一代这么传下来了。
页:
[1]