【发布时间】:2016-02-29 18:43:18
【问题描述】:
我需要关于我刚开始学习的汇编代码的帮助。
.intel_syntax noprefix;
.text;
.globl main;
main:
mov eax, 3;
mov ebx, 0;
push eax;
push ebx;
call f;
add esp, 8;
push eax;
mov eax, offset message;
push eax;
call printf
add esp,8;
mov eax,0;
ret;
f:
mov eax, [esp+8];
mov ebx, [esp+4];
cmp eax,3;
jge ety2;
cmp eax,2;
je ety1;
cmp eax,0;
je ety1;
cmp eax,1;
je ety3;
ety3:
mov eax,0;
ret;
ety1:
mov eax,1;
ret;
ety2:
xor ebx,ebx;
dec eax;
push eax;
push ebx;
call f;
add esp,8;
add ebx,[esp+4];
add ebx,eax;
mov eax,[esp+8];
dec eax;
dec eax;
push eax;
push ebx;
call f;
add esp,8;
add ebx,[esp+4];
add ebx,eax;
add ebx,eax;
mov eax,[esp+8];
dec eax;
dec eax;
dec eax;
push eax;
push ebx;
call f;
add esp,8;
add ebx,[esp+4];
sub ebx,eax;
mov eax,[esp+8];
mov eax,ebx;
ret;
.data;
message:
.asciz "Result=%i\n";
.att_syntax prefix;
在主函数中,“eax”寄存器用作函数的“n”参数:
for n=0 or n=2 returns 1;
for n=1 returns 0;
for n>=3 returns f(n-1)+(2*f(n-2))-f(n-3);
所以对于 n=3 函数返回 0,n=4 返回 2,n=5 返回 1,n=6 返回 5 e.t.c.
递归是非常有问题的,对于值
需要使用“PUSH”和“[esp+4]”,“add esp,4;”以及代码中已经存在的其他简单指令。 程序在-m32命令参数下编译(gcc -Wall funcas.s -m32 -o test)。
我在 C 中写下了相同的代码来展示我想要实现的目标
#include <stdio.h>
#include <stdlib.h>
int funkcja(int n)
{
if(n>=3)
{
return (funkcja(n-1)+(2*funkcja(n-2))-funkcja(n-3));
}
else
{
if(n==2)return 1;
if(n==1)return 0;
if(n==0)return 1;
}
return -1;
}
int main()
{
int a=6;
printf("%d\n", funkcja(a));
return 0;
}
【问题讨论】:
-
请修正缩进,以便您的代码可读。 (例如,说明比标签缩进一级)。那堵asm的墙让我想停止阅读。所以我只想说,要编写递归函数,你必须保存/恢复任何需要在函数调用中生存的状态的寄存器,如果有任何不在堆栈上的话。 (例如,当您计算涉及三个递归调用的表达式时的临时变量)。
-
您也可以努力调试它。调试汇编代码非常简单。
-
在
f中,您需要在进入时保留ebx中的内容(至少)并在返回给调用者之前恢复它。您可以使用push/pop ebx做到这一点,但您需要调整偏移量以访问参数。
标签: gcc assembly 32-bit gnu-assembler