Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在按下/弹出其他寄存器的同时,从堆栈中访问相对于EBP的函数参数?_C_Assembly_X86_Nasm_Calling Convention - Fatal编程技术网

C 在按下/弹出其他寄存器的同时,从堆栈中访问相对于EBP的函数参数?

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:

我正在编写汇编程序和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:
    $(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