计算机系统基础-学习记录4

程序的机器级表示:基础(续)

汇编基础(续)

将C语言转换为目标代码(机器语言)(续)

  高级语言通过编译器,变为汇编语言或机器语言。汇编语言通过汇编器变成机器语言。最后经过链接器,形成最后的exe文件

  链接分为静态链接和动态链接:
  静态链接:直接拷贝代码
  动态链接:动态执行

  Windows:
  静态库:*.lib
  动态库:*.dll

  Linux:
  静态库:*.a
  动态库:*.so

  gcc编译器采用ATT标准的Intel汇编格式。不同的编译器可能会导致汇编语言不同

数据类型

  1/2/4/8字节分别用DB,DW,DD,QD表示

  汇编语言中没有集合类型(例如结构体、数组等)

底层(支持)的主要操作

  1、算术操作(+、-、*、/、>>、<<)

  2、逻辑操作

  3、访存(比较出名的有Move指令)
从内存中读取数据,送至寄存器
把寄存器数据写往内存

  4、转移控制
高级语言的跳转指令能够使用,是因为底层能够支持转移控制指令

  以上四大指令,任何系统都必须支持,只有这样才能正确执行,完成一件事情

debugger重要性

  debugger具有跟踪的能力,在ide中使用debugger编译出的exe比release编译出的exe要大得多。debugger主要是为了方便调试,当不再需要调试时,可以不用debugger

  在多线程时,不使用debugger会导致“找不到”

汇编基础:寄存器、操作数、移动

寄存器

  在CPU中的寄存器非常有限,因为会增加功耗并影响集成度

  x86-64寄存器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X0lfr9RL-1602512558133)(C:\Users\蔡三圈\AppData\Roaming\Typora\typora-user-images\image-20201009150322713.png)]

  8位机时只有四个寄存器,之后逐渐扩展。最开始时,每个寄存器都具有意义,因此都具有特别的名字。而现在除了%rsp之外,其他的都没有专门用途了(例如曾经,寄存器中加入了对字符串的操作:%rsi,目前也不专门使用了),因此新增的寄存器(图右侧)都没有专门取名

  目前唯一具有特定功能的寄存器是%rsp,永远指向栈顶的地址。栈顶是小地址,栈底是大地址

  IA32寄存器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s5dglhCh-1602512558139)(C:\Users\蔡三圈\AppData\Roaming\Typora\typora-user-images\image-20201009151011528.png)]

  如果是16位机,则只能使用寄存器右半段的部分

移动数据

  ATT格式:
  movq Source, Dest;

  ATT格式和Intel是反过来的,Intel是Dest在前,Source在后

  操作数类型:
  1、立即数:常整数,类似于C中的常量,但前面加入了前缀"$"。例如:$0x400
  2、寄存器:%rax等
  3、地址模式(内存):(%rax)等,括号表示从地址中取来的数

  地址模式中,D(Rb, Ri, S)表示Mem[Reg[Rb]+S*Reg[Ri]+D]的简写,其中,Reg[xx]表示寄存器xx的地址,Mem[yy]表示yy地址下的值

  源操作数和目标操作数的关系:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vQcsotXO-1602512558143)(C:\Users\蔡三圈\AppData\Roaming\Typora\typora-user-images\image-20201009151533379.png)]

  无法从一个地址源操作数移动到另一个地址目标操作数(因为冯诺依曼体系结构中处理器是计算机的核心,所有指令都要通过处理器完成,而在内存到内存的过程中无处理器参与)

  全局变量读取较慢,尽量使用局部变量(局部变量在寄存器中,取出来非常快)

算术运算与逻辑运算

计算地址的指令

  leaq Src, Dst
  将源操作数的地址送给目的操作数

  在不引用内存的情况下计算地址。不同于movq,movq计算地址后,还要取那个地址上的值来赋给目的操作数,而leaq则是直接把计算出的地址赋给目的操作数(没有取那个地址上的值)

  理解:寄存器存的是地址,例如在movq时,(%rax)是取了寄存器%rax存储的地址/上的值,而leaq时的(%rax)则是直接把%rax存储的地址给拿了出来当做一个值来用

  例如:leaq (%rdi, %rdi, 2), %rax,等价于t = x+x*2

算术运算

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6uHx3T1G-1602512558149)(C:\Users\蔡三圈\AppData\Roaming\Typora\typora-user-images\image-20201011130819367.png)]

  算术运算分为加载有效地址、单操作数运算、双操作数运算和移位

程序的机器级表示:控制

  特殊处理器(%rip:指令指针):在Intel中叫ip,在其他地方叫PC

处理器状态

  除了整数寄存器外,还有一组单个位的条件码寄存器,用于描述最近的算术或逻辑操作的属性,可以据此实现条件分支命令的执行

  最常用的四个条件码:CF、ZF、SF、OF
  CF(Carry Flag):进位标志:最近的操作是否使最高位产生了进位(“无符号型”数的溢出)
  ZF(Zero Flag):零标志:最近的操作是否得出结果0
  SF(Sign Flag):符号标志:最近的操作是否得到负数结果
  OF(Overflow Flag):溢出标志:最近的操作是否导致一个补码溢出(正溢出或负溢出)

  运算时会视情况更新四个标签,例如:在运行t = a+b时:
  如果最高位进位(“无符号型”数的溢出),则CF=1
  如果t==0,则ZF=1
  如果t<0,则SF=1
  如果发生了符号溢出,即(a>0 && b>0 && t<0) || (a<0 && b<0 && t>=0),则OF=1

  在leaq指令运行时,不会更新这四种状态,因为leaq是用地址进行计算的

cmp指令

  cmpq Src2, Src1
  比较两数的大小
  会像计算Src1-Src2那样,只更新条件码,不更新目的寄存器
  在cmpq b, a中:
  当两数为无符号类型时,如果发生了溢出,则CF=1
  如果a==b,则ZF=1
  如果(a-b) < 0,则SF=1
  如果(a-b)发生符号溢出,则OF=1

test指令

  testq Src2, Src1
  相当于计算Src1 & Src2,更新状态的规则同上

SetX指令

  用于设置寄存器的最低字节(只更新最低字节,其余七个字节不动)
  例如:

cmp $eax,%edx
setb %cl

  表示先比较$eax, %edx的大小,更新flag寄存器中的值。再根据flag来判断的结果,将%cl置0或1

  常见的Set-指令:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tRZ5Vkto-1602512558151)(C:\Users\蔡三圈\AppData\Roaming\Typora\typora-user-images\image-20201012215219622.png)]

  表中Condition是flag的表达式,使用这些指令时,会根据这些表达式来更新相应的寄存器(值为0或1)。例如:在使用指令setl %xxx时,会根据(SF^OF)的值,来更新相应的寄存器%xxx

条件分支指令

跳转

jX指令

  跳转至代码的其他部分的条件码

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EmJ5HTvw-1602512558155)(C:\Users\蔡三圈\AppData\Roaming\Typora\typora-user-images\image-20201012221834368.png)]

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值