当前位置: 首页 > 知识库问答 >
问题:

x86 汇编语言中的函数调用

吴峰
2023-03-14

我很难理解由一个简单的C程序的gcc创建的汇编语言输出。

以下是该程序的C代码:

#include <stdio.h>
#include <stdlib.h>

int sum1=1;
int sum2=1;

int add(int s1, int s2){
    return s1+s2;
}

int main(int argc,char** agrv){
    int res=sum1+sum2;
    return 0;
}

下面是gcc创建的汇编代码:

    .file   "main.c"
    .globl  sum1
    .data
    .align 4
sum1:
    .long   1
    .globl  sum2
    .align 4
sum2:
    .long   1
    .text
    .globl  add
    .def    add;    .scl    2;  .type   32; .endef
    .seh_proc   add
add:
    pushq   %rbp
    .seh_pushreg    %rbp
    movq    %rsp, %rbp
    .seh_setframe   %rbp, 0
    .seh_endprologue
    movl    %ecx, 16(%rbp)
    movl    %edx, 24(%rbp)
    movl    16(%rbp), %edx
    movl    24(%rbp), %eax
    addl    %edx, %eax
    popq    %rbp
    ret
    .seh_endproc
    .def    __main; .scl    2;  .type   32; .endef
    .globl  main
    .def    main;   .scl    2;  .type   32; .endef
    .seh_proc   main
main:
    pushq   %rbp
    .seh_pushreg    %rbp
    movq    %rsp, %rbp
    .seh_setframe   %rbp, 0
    subq    $48, %rsp
    .seh_stackalloc 48
    .seh_endprologue
    movl    %ecx, 16(%rbp)
    movq    %rdx, 24(%rbp)
    call    __main
    movl    sum1(%rip), %edx
    movl    sum2(%rip), %eax
    addl    %edx, %eax
    movl    %eax, -4(%rbp)
    movl    $0, %eax
    addq    $48, %rsp
    popq    %rbp
    ret
    .seh_endproc
    .ident  "GCC: (x86_64-posix-seh-rev2, Built by MinGW-W64 project) 7.1.0"

我很难理解汇编代码中某些指令的操作数顺序(参考内存布局,请参阅内存布局图)。首先,有指令

    pushq   %rbp

它将调用方的基指针推送到堆栈上。这条指令之后是下面的指令:

    movq    %rsp, %rbp

此指令应将被调用方的基指针设置为当前堆栈指针的值。但是,两个操作数的顺序是否应该相反(例如,movq%rbp,%rsp)?

类似的“问题”出现在指令中:

    addl    %edx, %eax

到目前为止,我在互联网上查阅的几乎所有来源都声称指令的结果存储在指令的第一个参数中?

共有1个答案

吕霖
2023-03-14

GNU编译器在“AT”中生成程序集

GNU汇编程序gas使用与任何x86参考手册中可能找到的语法不同的语法,并且双操作数指令的源和目的地顺序相反。以下是气体说明的类型:

opcode                    (e.g., pushal)
opcode operand            (e.g., pushl %edx)
opcode source,dest        (e.g., movl %edx,%eax) (e.g., addl %edx,%eax)

如果有两个操作数,最右边的一个是目的地。最左边的是源。

 类似资料:
  • 本文向大家介绍Intel x86 Assembly& Microarchitecture x86汇编语言,包括了Intel x86 Assembly& Microarchitecture x86汇编语言的使用技巧和注意事项,需要的朋友参考一下 示例 x86汇编语言家族代表了最初的Intel 8086架构数十年来的进步。除了基于所使用的汇编器的几种方言外,多年来添加了附加的处理器指令,寄存器和其他功

  • 我们一段代码来研究函数调用的过程。首先我们写一段简单的小程序: int sum(int c, int d) { int e = c + d; return e; } int func(int a, int b) { return sum(a, b); } int main(void) { func(2,3);

  • 你可以使用在线汇编或者用汇编写整个子程序然后再连接到你的工程中。 如果你选择后者,建议你选择可以将高级语言直接编译成汇编的编译器。 这样你可以得到正确的函数调用原型。 所有的 C++ 编译器都能做这个工作。 传递参数的方法取决于调用形式: 调用方式 参数在堆栈里的次序 参数由谁来移去 _cdecl 第一个参数在低位地址 调用者 _stdcall 第一个参数在低位地址 子程序 _fastcall 编

  • 所以项目要求我填充未初始化的数组,我做到了。但它也要求我按降序对这个数组进行排序,然后将数组的中间元素放入eax寄存器,并调用dumpregs。这是我陷进去的部分。任何关于如何进行的帮助都是很好的。谢谢!

  • 是否可以在x86汇编语言中模拟if-statment(使用masm语法)?我想在x86汇编语言中做这样的事情,但我不确定应该使用哪个运算符来模拟if-ore语句。我应该使用指令,还是指令,还是其他指令?

  • 机器语言 机器语言是指令的集合。 汇编语言 汇编语言的主体是汇编指令。 存储器 随机存储器RAM,可读可写,必须带电存储,关机后存储的内容丢失 只读存储器ROM,只读,关机后其中的内容不丢失 装有 BIOS (基本输入输出设备)的ROM 接口卡上的RAM:显存 外存(storage,磁盘)和内存(memory,主存,高速缓存) 内存地址空间 存储单元:1个字节(byte) 总线 地址总线:CPU是