深入理解计算机系统学习笔记

第二章

汇编

汇编入门

汇编示例

在这里插入图片描述
编译运行.s文件:

as 1005.s -o 1005.o
ld 1005.o -o 1005
./1005

编译调试.s文件:1005.o不可执行,但是链接后生成的1005可以执行

as -g 1005.s -o 1005.o
ld 1005.o -o 1005
gdb -q 1005

反汇编可执行文件:

objdump -d 1011
数据传输

movl movw movb 分别传送32位 16位 8位数据:

movl $4,%eax
movw $1,%ax
movb $0x65,%dh

如果只写mov,机器会根据寄存器名字补全l/w/b,若往%bx(16位寄存器 )传输了32位数据,机器会报错。

  • 引入变量名:
    movl %ecx,value1 e.g. value1为int型的整数1,此处将%ecx的内容传给value1所在的内存地址,即更新了value1 的值。
    movl value1,%ecx e.g. value1为int型的整数1,此处将从value1的地址开始从内存取4个字节的内容放到%ecx里面,即将value1的值赋值给%ecx。
    movl $value1,%ecxe.g. value1为int型的整数1,此处将value1的地址放到%ecx里面。
  • 引入leal指令,专门用来传输地址
    movl $value1,%ecx == leal value1,%ecx
    leal 5(%edx,%edx,2),%eax e.g. %edx=x,计算
  • 没有内存到内存的数据传输,原因有二:1. 既然不需要经过CPU,那么可以由内存自己进行 2. 对于如下的指令,89代表%ecx,0d代表mov指令,a4 90 04 08 代表地址,所以如果前后都是内存地址,指令长度不够
    在这里插入图片描述
寻址方式
  1. 查看内存内容:x/4bt 0x11223344 或者 x/4bt $eax 注意是$符号
    在这里插入图片描述
  2. 查看变量的值:print value 查看变量在内存中的地址 :print &value
  • 立即数寻址 movl $1,%eax

  • 寄存器寻址movl %ebx,%eax

  • 绝对寻址movl 0x08048054,%eax 这里的内存地址只是一个起始地址,具体传几位数据,由movl和%eax决定

  • 间接寻址movl (%ebx),%eax 从寄存器获取内存地址,作为绝对寻址的目标地址

  • 基址偏移量寻址movl 0x8(%ebx),%eax先从寄存器获取内存地址,加上偏移量,作为绝对寻址的目标地址

  • 变址寻址 movl (%ebx,%edx),%eax 访问数组 或者 循环结果中常用,e.g %ebx存储为2,%edx存储为0x11223344,则绝对寻址的目标地址为0x11223346

  • 比例变址寻址 movl (%ebx,%ecx,0x2),%eax e.g %ebx存储为0x08048056,%ecx存储为2,则绝对寻址的目标地址为0x0804505a

汇编进阶

栈操作指令
  • 栈顶指针朝低地址方向增长
  • gdb查看栈顶指针地址:print $esp
  • e.g. %esp首先在0x0bffff29c,push %ebx (%ebx = 0x12345678),则push后,%esp到了0x0bffff298(上移4字节),0x0x0bffff298-0x0x0bffff29b分别存放0x78,0x56,0x34,0x12(低地址放低位数据)
  • e.g. push value VS push $value 前者从变量value存放的内存地址取值push入栈,后者把value的内存地址push入栈
算数逻辑操作指令

在这里插入图片描述

跳转指令
  • %eip寄存器:存放下一条要执行的指令的地址,%eip不允许被代码直接修改,编译会报错
  • 直接跳转指令:jump (无条件跳转)
  • %eflags寄存器:
  • 条件跳转指令:
    汇编执行的思路:cmp x,y 根据y-x的结果,设置CF(进位标志),OF(溢出标志),SF(计算结果的最高位),ZF的各个位(存储在%eflags),再根据需求判断用到的位
  • ja无符号数 jg有符号数
循环指令

可以用跳转指令实现,也可以用loop指令实现

期中考试

通用32位CPU 常用寄存器及其作用

32位CPU所含有的寄存器有:
4个数据寄存器(EAX 累加器、EBX 基址寄存器、ECX 计数寄存器和EDX 数据寄存器)
2个变址和指针寄存器(ESI和EDI)
2个指针寄存器(ESP和EBP)
6个段寄存器(ES、CS、SS、DS、FS和GS)
1个指令指针寄存器(EIP)
1个标志寄存器(EFlags)

杂乱知识点集锦

  1. leave指令,还原程序现场,还原%ebp,%esp
  2. ret指令从栈中弹出地址,并返回到call指令后的那条指令
  3. movzbl 指令,传输数据并用0扩展;movsbl 指令,传输数据并用1扩展
  4. 汇编过程:从源文件到可执行文件的执行过程是:预编译->编译->汇编->链接
  5. 间接寻址和寄存器寻址 注意区分
  6. 补码的非运算:
  7. CPU要访问的某一存储单元的实际地址称(物理地址),程序存储器是通过(虚拟地址 )来寻址,汇编器将指令存放在代码段中的地址称为(指令地址)
  8. 指令计数器 PC属于控制器
  9. 堆栈指针 %esp 的内容是栈顶单元地址
  10. 跳转指令 :above 无符号
  11. CF ZF SF OF 进位 零 符号位 溢出
    对于Z = X + Y , (unsigned)z < (unsigned)x 表示无符号溢出,判断CF;(x < 0 == y < 0) && (z < 0 != x < 0) 表示有符号溢出,判断OF
  12. 求指定位数的补码:先写绝对值,若是负数,则按位取反加一
  13. 浮点数
    对阶码:小阶码调整到与大阶码相同的
    阶码E用移码表示,尾数用原码表示
    int向float转换:int型的有效位数是31,而float型小数域的有效位只有23位,也就是说int的二进制的有效位超过了24位,那么float型的小数域的精度就不够了。因此必须进行舍入。
  14. 函数栈调用
    在过程P调用过程Q时,先将参数按反序压栈(即从最后一个参数开始压栈),然后返回地址压栈,最后再将过程P的%ebp值 压栈
  15. 汇编指令LOOPE/LOOPZ是指CX不为零且标志ZF=1时循环
  16. 若int len = strlen(s),如果s=“hell”,则len=( ),字符串后有结束位’\0’,所以长度为5。但我实际写代码的时候并没有多出一位长度。
  17. 寄存器%eax, %ecx, %edx被划分为由调用者保存的寄存器. 寄存器%ebx, %esi, %edi被划分为由被调用者保存的寄存器。
  18. 函数指针int (*f)(int a,int b) f是函数名称,a,b是参数
  19. C语言中有符号数和无符号数进行运算(包括逻辑运算和算术运算)默认会将有符号数看成无符号数进行运算,其中算术运算默认返回无符号数,逻辑运算当然是返回0或1了。
  20. 有符号正数的原码、反码、补码都一样
  21. 并发运行是指一个进程的指令和另一个进程的指令是交错执行的。
  22. 汇编器(as)将hello.s翻译成机器语言指令,把这些指令打包成一种叫做可重定位目标程序的格式,并将结果保存在目标文件hello.o中
  23. 程序寄存器组是唯一能被所有过程共享的资源
  24. 文件是对I/O设备的抽象,虚拟存储器是对主存和磁盘的抽象,进程是对处理器、主存和I/O设备的抽象
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值