汇编与内联 x86-64

机器字长

x86是32位系统
64是64位系统

这里的32和64,指的都是机器字长

机器字长是

  1. 能直接进行整数/位运算的大小
  2. 指针的大小(索引内存的范围)

容易与机器字长混淆的概念:字

字=存储字长
字是MDR寄存器的位数,代表每个主存存储体中的存储单元可以存放的数据位数

8位机

由于空间大小限制,想要把集成电路做到个人主机里,只能用8位字长的

16位机

8086 IBMPC

32位机

Intel x86

64位机

32位到64位中间度过了很长的时间
在这里插入图片描述

C语言int类型

在这里插入图片描述

ABI

Application Binary Interface
计算机中的ABI是指应用程序二进制接口,它是编译器和链接器遵守的一组规则,以让编译后的程序可以正常工作。ABI里包含很多方面的内容,比如函数的调用顺序、数据类型的表示、可执行文件的格式、虚拟地址空间布局等等。不同的处理器体系结构有不同的ABI规范,例如X86和X86_64。ABI对于程序的兼容性和效率有重要的影响。

需求

gcc clang 编译出的程序能否互相链接

gcc 不同版本下 编译出的程序能否互相链接

C 和 C++ 的代码能否互相链接

实现

在linux下的 cdecl
在win32下的 stdcall

在这里插入图片描述

汇编

esp寄存器

计算机的esp寄存器是一个用来存储栈顶地址的寄存器。它可以指向内存单元,也可以指向内存单元之间的缝隙。它的值会随着栈的入栈和出栈操作而改变。它可以帮助CPU从栈中读取数据或指针。

eip寄存器

计算机的eip寄存器是一个用来存储下一条指令地址的寄存器。它可以帮助CPU从内存中读取指令并执行。它的值会随着指令的执行而改变。它和esp寄存器的区别是,esp寄存器是用来存储栈顶地址的寄存器,而eip寄存器是用来存储指令地址的寄存器。

汇编指令 sub $0x18,%esp

  • sub是减法指令,它表示将两个操作数相减,结果存放在第一个操作数中。
  • $0x18是一个立即数,它表示十六进制的18,也就是十进制的24。
  • %esp是一个寄存器,它表示栈指针,也就是指向栈顶的地址。
  • sub $0x18,%esp表示将栈指针减去24,也就是向下移动栈顶24个字节,相当于在栈上分配了24个字节的空间。在32位汇编(x86架构)中,机器字长为32位,等于4字节,也就是向下移动了6个栈帧。
  • 这个指令通常用于函数的开头,为函数的局部变量或参数预留空间。

eax寄存器

计算机的eax寄存器是:

  • 一个32位的通用寄存器,用于临时存储数据和内存访问。
  • 一个累加器,用于在乘法和除法指令中被自动调用。
  • 一个返回函数结果的寄存器,在win32中,一般用于保存函数的返回值。
  • 一个可以拆分的寄存器,它的低16位是ax,ax的高8位是ah,低8位是al。
  • 是64位寄存器rax的低32位

汇编指令 mov %esp,%eax

esp指向的地址的值移动到eax指向的地址

汇编指令 lea 0x1c(%esp),%eax

lea是load effective address的缩写,意思是加载有效地址。它的作用是把一个内存地址表达式的值(而不是该地址处的内容)存入一个寄存器。例如,lea eax, [ebx+4ecx]就是把ebx+4ecx的结果(一个地址值)存入eax寄存器,而不是把该地址处的数据存入eax寄存器。lea指令可以用来进行一些简单的算术运算,比如乘法和加法。

在这里插入图片描述
lea 0x1c(%esp),%eax
就是把esp上移0x1c个地址(7个栈帧),然后把这个地址值传给eax

汇编指令 push %eax

汇编指令 push 是将源操作数复制到堆栈中,同时减少栈指针 ESP 的值

就是把eax寄存器的值放到esp指向的栈帧地址,然后把esp下移1个栈帧

而结合上一步lea的指令来看,eax寄存器存放的是eap上移7个栈帧的地址

汇编指令 call 510 <bar>

把返回地址放到esp指向的位置,然后esp下移1个栈帧。

寄存器

在这里插入图片描述
在这里插入图片描述
64位不再用堆栈去传递参数,直接用6个参数寄存器去传递

在这里插入图片描述
在这里插入图片描述

rip寄存器

rip寄存器是一个64位的指令指针寄存器,用来保存当前正在执行的指令的地址或下一条要执行的指令的地址。rip寄存器可以用来实现一种新的寻址模式,称为rip相对寻址,使用这个模式,有效地址的计算方式变为rip(指向下一条指令)加上位移量。

在这里插入图片描述
汇编命令lea (%rdi,%rsi,1) %r9d。lea是load effective address的缩写,意思是加载有效地址。它的作用是把一个内存地址计算出来,然后存放到目的寄存器中2。它不会访问内存,也不会改变标志位。在这个命令中,%r9d是目的寄存器,(%rdi,%rsi,1)是源操作数,表示一个内存地址。这个地址的计算方法是把%rdi和%rsi的值相加,然后乘以1(即不变),再加上一个偏移量(如果有的话)。在这里没有偏移量,所以就是%rdi+%rsi。所以这个命令的意思是把%rdi+%rsi的结果存放到%r9d中。这个命令可能用于计算数组元素的地址或者进行简单的算术运算。

在这里插入图片描述
bss是计算机编程中的一个术语,表示包含静态分配的未初始化变量的内存区域。bss的全称是block started by symbol,源自IBM 704的汇编语言。bss区域通常不占用目标文件的空间,而是由程序加载器在加载程序时分配内存。bss区域中的变量通常被初始化为零或空指针。在C语言中,如果一个静态分配的对象没有显式的初始值,它就会被放在bss区域。

inline assembly

inline assembly是一种编译器的特性,它允许在C或C++程序中使用asm关键字嵌入汇编语言的源代码 。它在C中是有条件支持和实现定义的,但在C++中不支持。它可以使用作用域内的任何变量或函数名,比单独的汇编器更方便。它通常用于提高速度,经常用于系统编程。

遇到的汇编指令总结

在这里插入图片描述
pxor 异或操作 ,其实就是模二加运算(相同为0,不同为1) 自己和自己异或就是置零的操作
movsd 移动和合并double类型数据,占8个字节,
movss 移动和合并float类型数据,占4个字节,

获取随机数的两种办法

rdrand 指令:从Intel的CPU获取随机数
syscall:向操作系统要一个随机数

猜你喜欢

转载自blog.csdn.net/AiTanXiing/article/details/130271804