前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >程序的机器级表示

程序的机器级表示

作者头像
changan
发布2020-11-04 09:38:48
3170
发布2020-11-04 09:38:48
举报
文章被收录于专栏:巡天遥看一千河

CSAPP

机器级表示

汇编

  • 两个抽象
    • 硬件 指令集 ISA 的抽象
    • 虚拟内存 大数组
  • 汇编与高级语言的区别
    • 暴露的可操作
      • 程序计数器 rip
      • 条件寄存器
      • 整数寄存器
  • ATT 汇编与 intel 汇编区别
    • intel 省略了 指示大小的后缀
    • Intel省略了 寄存器前的 %
    • Intel 有很多不同的方法 描述内存的位置
    • 多个操作数 Intel 列出的操作数 是相反的

访问信息

  • 不同类型操作数
    • 寄存器
    • 立即数
    • 内存引用
  • 数据传送
    • mov S , D
  • 入栈出栈
    • push
      • sub %rsp; mov xxx (%rsp)
    • pop
      • mov %rsp xxx , add %rsp
    • pic
  • lea
    • load effective addr
      • 加载有效地址
    • lea s , d -> d=&s

控制

  • 条件码寄存器
    • CF 进位标志
    • ZF 零标志
    • SF 符号标志
    • OF 溢出标志
  • 访问条件码
    • 可以依据条件码的某种组合,将一个字节设置成0或1
      • SET 指令
        • setne D -> D=~ZF
    • 可以条件跳转到程序的其他部分
    • 可以有条件的传送数据
  • 跳转指令
    • 无条件跳转
      • jmp
        • 直接跳转
          • 跳转目标是作为指令的一部分编码
        • 间接跳转
          • 跳转目标是从寄存器或内存位置读出
    • 有条件跳转
      • 例子
        • jnz
        • jz
        • jne
      • 条件跳转只能 直接跳转
    • 跳转指令的编码
      • 跳转指令有几种不同的编码,最常用的是 PC相对的
        • PC-relative
          • 地址偏移量编码为 1 2 4字节
          • 指令编码很简洁
          • 目标代码可以不做改变就移到内存不同的位置
      • 绝对地址
        • 4个字节直接指定目标
  • 分支、循环、switch

过程

  • 概念
    • 用指定的一组参数和可选的返回值实现某种功能
  • 转移控制
    • 过程
      • 压栈,设置%rip ; 弹出地址,设置%rip
    • 跳转
      • 直接跳转
      • 间接跳转
  • 传递数据
    • 寄存器传参
      • rdi rsi rdx rcx r8 r9
    • 超过6个参数
      • 栈上传参
  • 分配和回收内存
    • 栈上的局部存储
      • 变量取地址
      • 结构
    • 寄存器局部存储
      • 寄存器保存惯例
        • 被调用者保存寄存器
          • rbp rbx r12~r15
          • %rbp 是栈帧指针,用于标识当前栈帧的起始位置
          • leave 指令来实现两条命令
          • movq %rbp, %rsp
          • popq %rbp
  • 实现基础
    • 运行时栈
      • 过程需要的存储空间超出寄存器大小,在栈上分配的数据称栈帧

结构与数组

  • 数组
    • movl (%rdx , %rcx , 4) , %rax
  • 结构
    • 通过首地址的相对偏移

过程的详细解释

代码语言:javascript
复制
void proc(long a1, long*a1p , int a2 , int* a2p, short a3, short* a3p , char a4, char* a4p  )
{
    *a1p += a1;
    *a2p += a2;
    *a2p += a3;
    *a4p += a4;
}


int main()
{
    long a1 = 0x12345678; 
    long*a1p = &a1;
    
    int a2 = 0x66666666; 
    int* a2p = &a2;

    short a3 = 0x3333; 
    short* a3p = &a3;
    
    char a4 = 0xFE; 
    char* a4p = &a4;
    
    proc( a1 ,a1p , a2, a2p, a3, a3p,a4 , a4p  );
    
    a1 = 0x11112222;
    a2 = 0x66669999;

    return 0;
}

栈描述

代码语言:javascript
复制
int main()
{
  400565:   55                      push   %rbp
  400566:   48 89 e5                mov    %rsp,%rbp
  400569:   48 83 ec 40             sub    $0x40,%rsp
    long a1 = 0x12345678; 
  40056d:   48 c7 45 d8 78 56 34    movq   $0x12345678,-0x28(%rbp)
  400574:   12  
    long*a1p = &a1;
  400575:   48 8d 45 d8             lea    -0x28(%rbp),%rax           // 先构造了一些 局部变量
  400579:   48 89 45 f8             mov    %rax,-0x8(%rbp)
    
    int a2 = 0x66666666; 
  40057d:   c7 45 d4 66 66 66 66    movl   $0x66666666,-0x2c(%rbp)
    int* a2p = &a2;
  400584:   48 8d 45 d4             lea    -0x2c(%rbp),%rax
  400588:   48 89 45 f0             mov    %rax,-0x10(%rbp)

    short a3 = 0x3333; 
  40058c:   66 c7 45 d2 33 33       movw   $0x3333,-0x2e(%rbp)
    short* a3p = &a3;
  400592:   48 8d 45 d2             lea    -0x2e(%rbp),%rax
  400596:   48 89 45 e8             mov    %rax,-0x18(%rbp)
    
    char a4 = 0xFE; 
  40059a:   c6 45 d1 fe             movb   $0xfe,-0x2f(%rbp)
    char* a4p = &a4;
  40059e:   48 8d 45 d1             lea    -0x2f(%rbp),%rax
  4005a2:   48 89 45 e0             mov    %rax,-0x20(%rbp)
    
    proc( a1 ,a1p , a2, a2p, a3, a3p,a4 , a4p  );  
  4005a6:   0f b6 45 d1             movzbl -0x2f(%rbp),%eax       // 通过寄存器和栈 传参
  4005aa:   0f be f8                movsbl %al,%edi
  4005ad:   0f b7 45 d2             movzwl -0x2e(%rbp),%eax
  4005b1:   44 0f bf d0             movswl %ax,%r10d
  4005b5:   8b 55 d4                mov    -0x2c(%rbp),%edx
  4005b8:   48 8b 45 d8             mov    -0x28(%rbp),%rax
  4005bc:   4c 8b 4d e8             mov    -0x18(%rbp),%r9
  4005c0:   48 8b 4d f0             mov    -0x10(%rbp),%rcx
  4005c4:   48 8b 75 f8             mov    -0x8(%rbp),%rsi
  4005c8:   4c 8b 45 e0             mov    -0x20(%rbp),%r8
  4005cc:   4c 89 44 24 08          mov    %r8,0x8(%rsp)
  4005d1:   89 3c 24                mov    %edi,(%rsp)
  4005d4:   45 89 d0                mov    %r10d,%r8d
  4005d7:   48 89 c7                mov    %rax,%rdi
  4005da:   e8 11 ff ff ff          callq  4004f0 <proc>

gdb 调试

代码语言:javascript
复制
void proc(long a1, long*a1p , int a2 , int* a2p, short a3, short* a3p , char a4, char* a4p  )
{
  4004f0:   55                      push   %rbp
  4004f1:   48 89 e5                mov    %rsp,%rbp
  4004f4:   48 89 7d f8             mov    %rdi,-0x8(%rbp)
  4004f8:   48 89 75 f0             mov    %rsi,-0x10(%rbp)
  4004fc:   89 55 ec                mov    %edx,-0x14(%rbp)
  4004ff:   48 89 4d e0             mov    %rcx,-0x20(%rbp)
  400503:   44 89 c2                mov    %r8d,%edx
  400506:   4c 89 4d d8             mov    %r9,-0x28(%rbp)
  40050a:   8b 45 10                mov    0x10(%rbp),%eax
  40050d:   66 89 55 e8             mov    %dx,-0x18(%rbp)
  400511:   88 45 d4                mov    %al,-0x2c(%rbp)
    *a1p += a1;
  400514:   48 8b 45 f0             mov    -0x10(%rbp),%rax       // 寄存器 能传递6个参数
  400518:   48 8b 10                mov    (%rax),%rdx
  40051b:   48 8b 45 f8             mov    -0x8(%rbp),%rax        // 其余的参数可以相对 rbp 获取
  40051f:   48 01 c2                add    %rax,%rdx
  400522:   48 8b 45 f0             mov    -0x10(%rbp),%rax
  400526:   48 89 10                mov    %rdx,(%rax)
    *a2p += a2;
  400529:   48 8b 45 e0             mov    -0x20(%rbp),%rax
  40052d:   8b 10                   mov    (%rax),%edx
  40052f:   8b 45 ec                mov    -0x14(%rbp),%eax
  400532:   01 c2                   add    %eax,%edx
  400534:   48 8b 45 e0             mov    -0x20(%rbp),%rax
  400538:   89 10                   mov    %edx,(%rax)

call proc后, 这个过程会push main的调用地址的下一处,在proc里面也会push rbp, 通过打印内存的值,可以看到 rsp上 存储的变量信息, 选用的数字比较有规则,比如 0x12345678 , 0x 66666666 如下图:

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-11-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • CSAPP
    • 机器级表示
      • 汇编
      • 访问信息
      • 控制
      • 过程
      • 结构与数组
      • 过程的详细解释
      • 栈描述
      • gdb 调试
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档