实践流程1-在X86_64架构下

代码与汇编转换

通过教材可知,64位和32位在参数传递上存在差异。32位在传递参数的时候是直接通过堆栈进行传递,而64位在传递传输的时候是先将前6个参数依次传入rdi、rsi、rdx、rcx、r8、r9,然后剩余的参数像32位一样通过堆栈传递,在2.5的作业上用32位代码直接在64位上调用printf函数出现段错误的问题,教材这里直接说明了,就是这个差异导致的。
示例代码t.c:

#include <stdio.h>
int sub(int a,int b,int c,int d,int e,int f,int g,int h)
{
    int u,v,w;
    u = 9;
    v = 10;
    w = 11;
    return a+g+u+v;
}

int main()
{
    int a,b,c,d,e,f,g,h,i;
    a=1;
    b=2;
    c=3;
    d=4;
    e=5;
    f=6;
    g=7;
    h=8;
    i=sub(a,b,c,d,e,f,g,h);
}

 

在x86_64的openEuler上转为汇编代码并查看

 

 

 

gdb分析

使用gcc -g t.s -o t将t.s进行编译,可以通过cgdb t直接对汇编代码进行调试,查看。

使用b mainr开始单步执行。

函数在执行前,都会先将rbp推入堆栈。
使用s单步执行。

首先是main函数的变量定义,首先esp减少48,为a~h提供空间。
查看寄存器的值:用i r,查看对应内存中的值,用x 0x012345678abcdef

对应上图ebp的值,查看堆栈中的a~h的值:

 

代码与汇编转换

arm64架构下的的t.s:

.cpu generic+fp+simd
        .file   "t.c"
        .text
        .align  2
        .global sub
        .type   sub, %function
sub:
.LFB0:
        .cfi_startproc
        sub     sp, sp, #48
        .cfi_def_cfa_offset 48
        str     w0, [sp,28]
        str     w1, [sp,24]
        str     w2, [sp,20]
        str     w3, [sp,16]
        str     w4, [sp,12]
        str     w5, [sp,8]
        str     w6, [sp,4]
        str     w7, [sp]
        mov     w0, 9
        str     w0, [sp,44]
        mov     w0, 10
        str     w0, [sp,40]
        mov     w0, 11
        str     w0, [sp,36]
        ldr     w1, [sp,28]
        ldr     w0, [sp,4]
        add     w1, w1, w0
        ldr     w0, [sp,44]
        add     w1, w1, w0
        ldr     w0, [sp,40]
        add     w0, w1, w0
        add     sp, sp, 48
        .cfi_def_cfa_offset 0
        ret
        .cfi_endproc
.LFE0:
        .size   sub, .-sub
        .align  2
        .global main
        .type   main, %function
main:
.LFB1:
        .cfi_startproc
        stp     x29, x30, [sp, -64]!
        .cfi_def_cfa_offset 64
        .cfi_offset 29, -64
        .cfi_offset 30, -56
        add     x29, sp, 0
        .cfi_def_cfa_register 29
        mov     w0, 1
        str     w0, [x29,60]
        mov     w0, 2
        str     w0, [x29,56]
        mov     w0, 3
        str     w0, [x29,52]
        mov     w0, 4
        str     w0, [x29,48]
        mov     w0, 5
        str     w0, [x29,44]
        mov     w0, 6
        str     w0, [x29,40]
        mov     w0, 7
        str     w0, [x29,36]
        mov     w0, 8
        str     w0, [x29,32]
        ldr     w0, [x29,60]
        ldr     w1, [x29,56]
        ldr     w2, [x29,52]
        ldr     w3, [x29,48]
        ldr     w4, [x29,44]
        ldr     w5, [x29,40]
        ldr     w6, [x29,36]
        ldr     w7, [x29,32]
        bl      sub
        str     w0, [x29,28]
        ldp     x29, x30, [sp], 64
        .cfi_restore 30
        .cfi_restore 29
        .cfi_def_cfa 31, 0
        ret
        .cfi_endproc
.LFE1:
        .size   main, .-main
        .ident  "GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-39)"
        .section        .note.GNU-stack,"",%progbits

 

参数传递流程分析

arm中:str为存储,ldr为取。

posted on 2021-12-30 12:52  20191208孙汇阳  阅读(52)  评论(0编辑  收藏  举报