汇编:64位机器上,C语言的返回值

寄存器简单理解

在64位架构上,有些特殊寄存器:

bash 复制代码
RAX:返回值
RBX:被调用者保存
RCX:第四个参数
RDX:第三个参数
RSI:第四个参数
RDI:第三个参数
RBP:存放栈底指针
RSP:存放栈顶指针
R8:第5个参数
R9:第6个参数
R10~R15:被调用者保存
R8~R15属于普通寄存器,支持拆分,但是拆分的寄存器在命名规则上与特殊功能寄存器有所不同。32位拆分寄存器以D作为后缀(DWORD),16位寄存器以W作为后缀(WORD),8位则以B作为后缀(BYTE)。

常见汇编指令

bash 复制代码
1.NOP :交换指令,操作数为90,什么也不干
2.PUSH x:将x压入栈,esp先减再压数据
3.POP x: 将栈顶数据弹出到x中,esp递增
4.CALL x:将call指令下一条指令压入栈中,改变eip的值为x
5.RET: 将栈顶数据弹出到eip 若为RET X 表示esp再增加x字节
6.MOV  目的, 源:将源的值传给目的
7.LEA x1,x2:将x2的地址载入到x1
8.ADD x1,x2:x1=x1+x2,指令的计算结果将影响eflags寄存器
9.SUB x1,x2:x1=x1-x2,同add,不能同时是内存操作数
10. jmp x: 将eip的值改为x。 jmp -2意味着jmp指令的无限循环
11. jcc x:当条件满足时跳转到x
12. cmp x1, x2: 用于比较两个操作数的大小
13. test x1, x2:通过计算两个操作数的逻辑与位运算实现比较操作,根据结果设置eflags
14. AND x1,x2: x1 = x1&x2
15. OR x1,x2: x1 = x1|x2
16. XOR x1,x2: x1 = x1^x2 常用于清零,效率高xor eax eax
17. not x1: x1 = ~x1 
18. SHL x1,x2:x1=x1<<x2逻辑左移,右边补0,   SAL:算术左移
19. SHR x1,x2:x1=x1>>x2 逻辑右移,左边补0,  SAR:算术右移,左边补符号
20. IMUL/MUL: imul实现有符号数的乘法运算,mul是无符号乘法
	imul r/m32 eax=eax*r/m*32
	imul reg,r/m reg=reg*r/m32
	imul reg,r/m32,immediate reg=r/m32*immediate
21. IDIV/DIV: div用于实现无符号数的除法运算
	idiv ecx: eax / ecx 商放在eax,余数放在edx 
	div ax, r/m8 ; ax 除以 r/m8, al是商,ah是余数
	div eax,r/m32; eax除以r/m32,eax是商,edx是余数
	若被除数是32位数,在指令执行前edx被置为0
22. REP STOS; rep是前缀,表示重复执行某项操作
23. REP MOVS:重复执行movs操作
24. LEAVE: 用于子函数推出时清理栈的操作,ret和leave选择取决于编译器。  等价于mov  esp, ebp; pop ebp

函数返回值

使用 gcc -S demo.c 可以得到demo.s文件

此文件仅仅是在main函数中调用func01,

在main函数中,调用func01前,在栈顶%rsp开辟了16字节的栈【subq $16, %rsp】

在func01的汇编中,其返回值,被放入到%rax中【movabsq $8031924123371070824, %rax】

$8031924123371070824是堆中的地址

查看汇编

bash 复制代码
func01:
.LFB0:
        .cfi_startproc
        endbr64
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        subq    $32, %rsp
        movq    %fs:40, %rax
        movq    %rax, -8(%rbp)
        xorl    %eax, %eax
        leaq    .LC0(%rip), %rax
        movq    %rax, -32(%rbp)
        movabsq $8031924123371070824, %rax
        movq    %rax, -20(%rbp)
        movl    $6581362, -12(%rbp)
        movq    -32(%rbp), %rax
        movq    -8(%rbp), %rdx
        xorq    %fs:40, %rdx
        je      .L3
        call    __stack_chk_fail@PLT

main:
.LFB1:
        .cfi_startproc
        endbr64
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        subq    $16, %rsp
        call    func01
        movq    %rax, -8(%rbp)
        movq    -8(%rbp), %rax
        movq    %rax, %rsi
        leaq    .LC1(%rip), %rdi
        movl    $0, %eax
        call    printf@PLT
        movl    $0, %eax
        leave
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
相关推荐
knightkkzboy1 小时前
《C语言中的“魔法盒子”:自定义函数的奇妙之旅》
c语言·开发语言·函数
Dovis(誓平步青云)2 小时前
【数据结构】排序算法(下篇·终结)·解析数据难点
c语言·数据结构·学习·算法·排序算法·学习方法·推荐算法
leluckys11 小时前
swift-汇编分析多态原理、init
汇编
北冥有鱼被烹12 小时前
【工具】如何将一个脚本作为C语言的一个文件被include到新的C文件中然后执行?(C语言 array的方式)
c语言
旧时光林12 小时前
P10905 [蓝桥杯 2024 省 C] 回文字符串
c语言·c++·蓝桥杯·模拟·枚举
猫猫头有亿点炸14 小时前
C语言for循环嵌套if相关题目
c语言·开发语言
阿巴~阿巴~15 小时前
蓝桥杯速成刷题清单(上)
c语言·c++·算法·蓝桥杯
要下雨了吗18 小时前
指针数组 vs 数组指针
c语言·数据结构·c++·算法·visual studio
小郝 小郝19 小时前
【C语言】内存函数
c语言·开发语言
森焱森19 小时前
单片机FreeRTOSTickless低功耗模式应用示例
c语言·网络·单片机·算法·架构