在 64 位上返回 C 代码 x86 编译中的汇编函数 linux
returning Assembly Function In C Code x86 Compilation on 64 bit linux
C代码
#include <stdio.h>
int fibonacci(int);
int main()
{
int x = fibonacci(3);
printf("Fibonacci is : %d",x);
return 0;
}
程序集
section .text
global fibonacci
fibonacci:
push ebp;
mov ebp, esp;
; initialize
mov dword [prev], 0x00000000;
mov dword [cur], 0x00000001;
mov byte [it], 0x01;
mov eax, dword [ebp + 8]; // n = 3
mov byte [n], al;
getfib:
xor edx,edx;
mov dl, byte [n];
cmp byte [it] , dl;
jg loopend;
mov eax,dword [prev];
add eax, dword [cur];
mov ebx, dword [cur];
mov dword [prev], ebx;
mov dword [cur] , eax;
inc byte [it];
jmp getfib;
loopend:
mov eax, dword [cur];
pop ebp;
ret;
section .bss
it resb 1
prev resd 1
cur resd 1
n resb 1
我试图 运行 在 C 代码和调试中使用这个汇编函数,我看到 C 代码中变量 x 的值是正确的,但是当我使用 printf 函数时出现一些错误
需要帮助
编译命令:
nasm -f elf32 asmcode.asm -o a.o
gcc -ggdb -no-pie -m32 a.o ccode.c -o a.out
如果图片看起来模糊,请单击下面的图片
以下是printf执行前的调试
下面是printf执行后
您的代码不保留 ebx
寄存器,这是一个被调用者保留的寄存器。 main
函数显然试图做一些 rip
相对寻址,以使用 ebx
作为基址寄存器来获取 printf
的格式字符串的地址。这失败了,因为您的代码覆盖了 ebx
.
要解决此问题,请确保在使用之前保存所有被调用者保存的寄存器,然后在 return 上恢复它们的值。例如,你可以做
fibonacci:
push ebp
mov ebp, esp
push ebx ; <---
...
pop ebx ; <---
pop ebp
ret
C代码
#include <stdio.h>
int fibonacci(int);
int main()
{
int x = fibonacci(3);
printf("Fibonacci is : %d",x);
return 0;
}
程序集
section .text
global fibonacci
fibonacci:
push ebp;
mov ebp, esp;
; initialize
mov dword [prev], 0x00000000;
mov dword [cur], 0x00000001;
mov byte [it], 0x01;
mov eax, dword [ebp + 8]; // n = 3
mov byte [n], al;
getfib:
xor edx,edx;
mov dl, byte [n];
cmp byte [it] , dl;
jg loopend;
mov eax,dword [prev];
add eax, dword [cur];
mov ebx, dword [cur];
mov dword [prev], ebx;
mov dword [cur] , eax;
inc byte [it];
jmp getfib;
loopend:
mov eax, dword [cur];
pop ebp;
ret;
section .bss
it resb 1
prev resd 1
cur resd 1
n resb 1
我试图 运行 在 C 代码和调试中使用这个汇编函数,我看到 C 代码中变量 x 的值是正确的,但是当我使用 printf 函数时出现一些错误
需要帮助
编译命令:
nasm -f elf32 asmcode.asm -o a.o
gcc -ggdb -no-pie -m32 a.o ccode.c -o a.out
如果图片看起来模糊,请单击下面的图片
以下是printf执行前的调试
下面是printf执行后
您的代码不保留 ebx
寄存器,这是一个被调用者保留的寄存器。 main
函数显然试图做一些 rip
相对寻址,以使用 ebx
作为基址寄存器来获取 printf
的格式字符串的地址。这失败了,因为您的代码覆盖了 ebx
.
要解决此问题,请确保在使用之前保存所有被调用者保存的寄存器,然后在 return 上恢复它们的值。例如,你可以做
fibonacci:
push ebp
mov ebp, esp
push ebx ; <---
...
pop ebx ; <---
pop ebp
ret