C 在按下/弹出其他寄存器的同时,从堆栈中访问相对于EBP的函数参数?
我正在编写汇编程序和C程序;C程序将调用汇编语言编写的函数。环境是Ubuntu 18.04LTS x64 它是为32位x86设计的,将由NASM编译,但无法传递正确的参数 为了简化这个问题,我改变了我的函数,得到了a和b的和 该函数只是将a和b相加,然后返回总和。总和应该是2,但是我得到了一个像1449041840这样的随机数。程序集似乎没有获得正确的参数 代码有什么问题,我如何修复它C 在按下/弹出其他寄存器的同时,从堆栈中访问相对于EBP的函数参数?,c,assembly,x86,nasm,calling-convention,C,Assembly,X86,Nasm,Calling Convention,我正在编写汇编程序和C程序;C程序将调用汇编语言编写的函数。环境是Ubuntu 18.04LTS x64 它是为32位x86设计的,将由NASM编译,但无法传递正确的参数 为了简化这个问题,我改变了我的函数,得到了a和b的和 该函数只是将a和b相加,然后返回总和。总和应该是2,但是我得到了一个像1449041840这样的随机数。程序集似乎没有获得正确的参数 代码有什么问题,我如何修复它 # Makefile cc=gcc ASMBIN=nasm all : asm cc link asm:
# Makefile
cc=gcc
ASMBIN=nasm
all : asm cc link
asm:
$(ASMBIN) -o findpattern.o -f elf32 -l findpattern.lst findpattern.asm
cc :
$(cc) -m32 -c -g -O0 -fpack-struct graph_io.c
link :
$(cc) -m32 -o graph_io findpattern.o graph_io.o
clean:
rm *.o
rm graph_io
rm findpattern.lst
您的堆栈框架设置错误<代码>推ebp;在进行任何其他堆栈移动之前,必须发出mov ebp、esp 在设置
ebp
之前,通过在堆栈上推其他内容,您已经设置了ebp
指向与平常不同的位置,导致所有偏移量都不同。要解决此问题,请首先设置堆栈帧,然后按下其余寄存器:
global FindPattern
section .text
FindPattern:
push ebp
mov ebp,esp
push esi
push edi
push ebx
push edx
push ecx
mov esi,[ebp+8] ; a
mov edi,[ebp+12] ; b
mov eax,0
add eax,esi
add eax,edi ; return a+b
pop ecx
pop edx
pop ebx
pop edi
pop esi
pop ebp
ret
谢谢!我忘了这个!@Yi yezi Cool!如果这解决了您的问题,请不要忘记通过单击旁边的复选标记将答案标记为已接受。值得指出的是,ECX和EDX在标准调用约定中通常是“调用阻塞”的,即函数可以自由地将其用作临时/临时性的,而无需保存/恢复它们。其他寄存器(包括EBP和ESP)是保留调用的,如果您想使用它们,应该保存它们:C编译器希望这些寄存器在调用FindPattern后不会更改值,但确实希望EAX、ECX和EDX被销毁(或替换为EAX的返回值)
# Makefile
cc=gcc
ASMBIN=nasm
all : asm cc link
asm:
$(ASMBIN) -o findpattern.o -f elf32 -l findpattern.lst findpattern.asm
cc :
$(cc) -m32 -c -g -O0 -fpack-struct graph_io.c
link :
$(cc) -m32 -o graph_io findpattern.o graph_io.o
clean:
rm *.o
rm graph_io
rm findpattern.lst
global FindPattern
section .text
FindPattern:
push ebp
mov ebp,esp
push esi
push edi
push ebx
push edx
push ecx
mov esi,[ebp+8] ; a
mov edi,[ebp+12] ; b
mov eax,0
add eax,esi
add eax,edi ; return a+b
pop ecx
pop edx
pop ebx
pop edi
pop esi
pop ebp
ret