保存现场 通用寄存器 过程调用的机器级表示 栈 栈帧 参数传递 逆向工程

 

计算机系统基础(一):程序的表示、转换与链接-模块七 第2讲 选择和循环语句的机器级表示(2)-网易公开课 https://open.163.com/newview/movie/free?pid=WFVPGEQSL&mid=PFVPGFAAS

 

 

 

leal (%eax,%eax), %edx
将eax乘2,即左移1位,放到edx
 

 

 

 

递归比循环更消耗栈帧空间、指令条数

 

 

 

复杂的局部便来了被分配到栈中 eax
简单的直接放到寄存器中 edx
入口参数放入 ecx中
 

 

 

 

 

递归调用 

 

int sum(int n){
    if(n<=0){
        return 100;
    }else{
        return n+sum(n-1);
    }
}
     1          .file   "r.c"
     2          .text
     3          .globl  sum
     4          .type   sum, @function
     5  sum:
     6  .LFB0:
     7          .cfi_startproc
     8          endbr64
     9          pushq   %rbp
    10          .cfi_def_cfa_offset 16
    11          .cfi_offset 6, -16
    12          movq    %rsp, %rbp
    13          .cfi_def_cfa_register 6
    14          subq    $16, %rsp
    15          movl    %edi, -4(%rbp)
    16          cmpl    $0, -4(%rbp)
    17          jg      .L2
    18          movl    $100, %eax
    19          jmp     .L3
    20  .L2:
    21          movl    -4(%rbp), %eax
    22          subl    $1, %eax
    23          movl    %eax, %edi
    24          call    sum
    25          movl    -4(%rbp), %edx
    26          addl    %edx, %eax
    27  .L3:
    28          leave
    29          .cfi_def_cfa 7, 8
    30          ret
    31          .cfi_endproc
    32  .LFE0:
    33          .size   sum, .-sum
    34          .ident  "GCC: (Ubuntu 11.2.0-19ubuntu1) 11.2.0"
    35          .section        .note.GNU-stack,"",@progbits
    36          .section        .note.gnu.property,"a"
    37          .align 8
    38          .long   1f - 0f
    39          .long   4f - 1f
    40          .long   5
    41  0:
    42          .string "GNU"
    43  1:
    44          .align 8
    45          .long   0xc0000002
    46          .long   3f - 2f
    47  2:
    48          .long   0x3
    49  3:
    50          .align 8
    51  4:

 

 

int sum(int n){
    if(n==0){
        return 100;
    }else{
        return n+sum(n-1);
    }
}
     1          .file   "r.c"
     2          .text
     3          .globl  sum
     4          .type   sum, @function
     5  sum:
     6  .LFB0:
     7          .cfi_startproc
     8          endbr64
     9          pushq   %rbp
    10          .cfi_def_cfa_offset 16
    11          .cfi_offset 6, -16
    12          movq    %rsp, %rbp
    13          .cfi_def_cfa_register 6
    14          subq    $16, %rsp
    15          movl    %edi, -4(%rbp)
    16          cmpl    $0, -4(%rbp)
    17          jne     .L2
    18          movl    $100, %eax
    19          jmp     .L3
    20  .L2:
    21          movl    -4(%rbp), %eax
    22          subl    $1, %eax
    23          movl    %eax, %edi
    24          call    sum
    25          movl    -4(%rbp), %edx
    26          addl    %edx, %eax
    27  .L3:
    28          leave
    29          .cfi_def_cfa 7, 8
    30          ret
    31          .cfi_endproc
    32  .LFE0:
    33          .size   sum, .-sum
    34          .ident  "GCC: (Ubuntu 11.2.0-19ubuntu1) 11.2.0"
    35          .section        .note.GNU-stack,"",@progbits
    36          .section        .note.gnu.property,"a"
    37          .align 8
    38          .long   1f - 0f
    39          .long   4f - 1f
    40          .long   5
    41  0:
    42          .string "GNU"
    43  1:
    44          .align 8
    45          .long   0xc0000002
    46          .long   3f - 2f
    47  2:
    48          .long   0x3
    49  3:
    50          .align 8
    51  4:

  

cat /proc/cpuinfo
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 142
model name : Intel(R) Core(TM) i3-10110U CPU @ 2.10GHz
stepping : 12
cpu MHz : 2592.000
cache size : 4096 KB
physical id : 0
siblings : 1
core id : 0
cpu cores : 1
apicid : 0
initial apicid : 0
fpu : yes
fpu_exception : yes
cpuid level : 22
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc cpuid tsc_known_freq pni pclmulqdq monitor ssse3 cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single fsgsbase avx2 invpcid rdseed clflushopt md_clear flush_l1d arch_capabilities
bugs : spectre_v1 spectre_v2 spec_store_bypass swapgs itlb_multihit srbds mmio_stale_data retbleed
bogomips : 5184.00
clflush size : 64
cache_alignment : 64
address sizes : 39 bits physical, 48 bits virtual
power management:

 

 

 

        .file   "a.c"
        .text
        .globl  sw_test
        .type   sw_test, @function
sw_test:
.LFB0:
        .cfi_startproc
        endbr64
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        movl    %edi, -20(%rbp)
        movl    %esi, -24(%rbp)
        cmpl    $10, -20(%rbp)
        je      .L2
        cmpl    $15, -20(%rbp)
        jne     .L3
        movl    -24(%rbp), %eax
        addl    $1500, %eax
        movl    %eax, -4(%rbp)
        jmp     .L4
.L2:
        movl    -24(%rbp), %eax
        addl    $1000, %eax
        movl    %eax, -4(%rbp)
        jmp     .L4
.L3:
        movl    $300, -4(%rbp)
        nop
.L4:
        movl    -4(%rbp), %eax
        popq    %rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE0:
        .size   sw_test, .-sw_test
        .globl  main
        .type   main, @function
main:
.LFB1:
        .cfi_startproc
        endbr64
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        movl    $0, %esi
        movl    $9, %edi
        call    sw_test
        movl    $0, %eax
        popq    %rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE1:
        .size   main, .-main
        .ident  "GCC: (Ubuntu 11.2.0-19ubuntu1) 11.2.0"
        .section        .note.GNU-stack,"",@progbits
        .section        .note.gnu.property,"a"
        .align 8
        .long   1f - 0f
        .long   4f - 1f
        .long   5
0:
        .string "GNU"
1:
        .align 8
        .long   0xc0000002
        .long   3f - 2f
2:
        .long   0x3
3:
        .align 8
4:

  

int sw_test(int a, int b)
{
    int result;
    switch (a)
    {
    case 15:
        /* code */
        result = b + 1500;
        break;
    case 10:
        result = b + 1000;
        break;
    default:
        result = 300;
        break;
    }
    return result;
}
int main()
{
    sw_test(9, 0);
}

  

 

跳转表在目标文件的只读节中,按4字节边界对齐。
 

switch case

cmpl 无符号比较 ,当a<10,a-10 首位为1和7做无符号比较,a-10>7也成立

 

 

 

if-else

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

返回地址:call指令的下一条地址
eip  函数首地址
入口参数位置
 

 

 

 

计算机系统基础(一):程序的表示、转换与链接-模块七 第1讲 过程(函数)调用的机器级表示(2)-网易公开课 https://open.163.com/newview/movie/free?pid=WFVPGEQSL&mid=CFVPGF8QM

 

形成栈帧:改变esp内容,esp的内容指向新的地址 : 通过sub或and指令


在EAX中返回参数

 

 

 

 

 
准备阶段
pushl %ebp 保存现场  是将返回地址压栈 : 被调用过程将调用过程的栈帧的栈底压入自己的栈帧的栈底
movl %esp,%ebp 形成栈底

subl $24,%esp esp栈顶-24,新位置;ebp不变
movl $125,-12(%ebp) 在ebp-12的位置放入立即数125

movl -8(%ebp),%eax 将ebp-8,即80送到eax
movl %eax,4(%esp) 再送到esp+4的位置
即:将ebp-8送到esp+4的位置,即:将80送到esp+4

movl -12(%ebp),%eax
movl %eax,(%esp) 将125送到esp


退栈
movl %ebp,%esp 将ebp的内容送到esp,esp又指向了ebp:栈里的内容被清空、释放掉

 

 

 

 

 

 

 

 

  

先使用EAX EDX ECX :不用保存
不够用时
才使用EBX ESI EDI :使用前先保存
 
调用者P保存寄存器 EAX EDX ECX 调用者去执行保存,被调用者可以直接用
被调用者Q保存寄存器 EBX ESI EDI 被调用者去执行保存,
被调用者在使用它们之前需要先将它们的值保存到栈中再使用它们
 

 每个过程优先使用:  EAX EDX ECX 

 

EBP 帧指针寄存器:栈帧的底部 ESP栈指针寄存器 顶部

 

寄存器哪些在调用过程用 、被调用过程用 有约定

 

 

 

因为 所有过程 

调用者 被调用者  共享一套通用寄存器 GPR 

 

为什么要保存现场

计算机系统基础(一):程序的表示、转换与链接-模块七 第1讲 过程(函数)调用的机器级表示(1)-网易公开课 https://open.163.com/newview/movie/free?pid=WFVPGEQSL&mid=HFVPGF8J4

 

ESP  栈栈指针寄存器 

 

 

 

可执行文件放到存储空间中 

 

参数可能很多,需要放到存储空间中,通过栈传递 

 

 

posted @ 2016-12-07 20:01  papering  阅读(209)  评论(0编辑  收藏  举报