高级语言对应的汇编指令

已 c++ 为例 😐 ---------- 🙄

定义变量

在这里插入图片描述
也就是说单纯的定义一个变量,不给它初始化,系统认为这个变量是没有意义的,就决定不会为它分配内存空间所以自然也不会有对应的汇编代码。或者可以理解为编译器暂时把你定义的变量记录下来但没有通知系统去做一些别的事情。

但是当定义一些被 c++ 封装后的结构类型时,就不一样了:
在这里插入图片描述
在这里插入图片描述在这里插入图片描述没错,string 也是! 😐

变量初始化

先来看 bool 类型的初始化:
在这里插入图片描述
将 false 对应的值存入变量 b 的地址中,没毛病 😀,如果把 false 改为 true 就是 1:
在这里插入图片描述
可见 false 其实就是 0x0,true 就是 0x1

再来看 char 和 unsigned char 的初始化:
在这里插入图片描述
‘a’ 对应了 acsii 码的 0x61,所以相当于把 acsii 码存入变量的地址,如果是正数则 char 和 unsigned char 没有什么区别。但事实上就算用负数初始化 char 和 unsigned char,它们的值也是相同的:
在这里插入图片描述

再看宽字节的初始化:它使用 eax 做了一个中转,然后再把值存入变量的地址中。
在这里插入图片描述

string 类型:可以理解为先在某个内存里写入一串字符,然后下面的 call 会从这个地址里取值,然后给 s 赋值。
在这里插入图片描述

对于正数来讲,int 和 unsigned int 没有区别:
在这里插入图片描述

同样和 char / unsigned char 一样,用负数赋值这两个变量也会得到相同的汇编指令结果:
在这里插入图片描述
所以可以得出结论:unsigned 只是会改变显示,不会改变数值本身

float 的初始化就比较奇怪了:

movss:是将一个单精度数传输到 xmm 寄存器的低32位
xmm:专门做高精度浮点值运算,有8个分别为 xmm0 ~ xmm7

在这里插入图片描述double 和 float 基本一样:
在这里插入图片描述
short 需要用 eax 做一下中转,而 long 和 longlong 都是直接赋值:
在这里插入图片描述

指针类型:nullptr 被当作 0 处理,对指针进行赋值使用 lea指令,rax 寄存器作为中转,最后由 rax 赋值给 p。
在这里插入图片描述

结构体:结构体对象地址也存放在基地址寄存器(rbp)中,然后通过成员在结构体中对应的偏移进行访问。
在这里插入图片描述

那么问题来了,直接再定义的时候赋值和先定义再赋值的汇编代码一样么?
答案是肯定的,因为我们上面已经验证了值定义一个变量不初始化是不会有对应的汇编代码的:
在这里插入图片描述
初始化一个数组:

rbp:基址指针寄存器,用于提供堆栈内某个单元的偏移地址

在这里插入图片描述
这里其实我们就可以推断出 a[] 的基地址是 rbp+18h 了 (也就是a[0] 的地址)

初始化一些特殊结构

其实也是调用了封装好的功能,主要是执行 call 指令:
在这里插入图片描述

输出 / 输入

同样也是调用 call 来实现:
在这里插入图片描述

调用函数

参数从右向左入栈,前4个参数存放在 rcx,rdx,r8,r9 中,之后的参数由 rax 作为中转存放在堆栈(rsp)中:
在这里插入图片描述
调用 API,依然遵从之前的参数入栈顺序,没由什么区别:
在这里插入图片描述

逻辑运算

+:将变量存入寄存器,使用 add 指令相加再存入寄存器,最后寄存器的值存入变量地址
在这里插入图片描述-:和+ 相同,但指令变成 sub
在这里插入图片描述

*:第一个操作数存入寄存器,调用 imul 指令完成有符号乘法并将结果存入寄存器,最后把寄存器的值存入变量地址中。

imul :有符号乘法指令
mul:无符号乘法指令

在这里插入图片描述

/:第一个操作数存入寄存器,调用 idiv 指令完成有符号除法并将结果存入寄存器,最后把寄存器的值存入变量地址中。

idiv:有符号除法
div:无符号除法

在这里插入图片描述

%:除法指令前多一个 cdq 指令

cdq:将一个32位有符号数(eax)扩展为64位有符合数(edx)

在这里插入图片描述

++: inc 累加指令
在这里插入图片描述

- -: dec 累减指令
在这里插入图片描述

连等:cmp 和 jne
在这里插入图片描述

不等: cmp 和 je
在这里插入图片描述

> 和 <: jle 和 jge
在这里插入图片描述

大于等于和小于等于:jl 和 jg
在这里插入图片描述

&&:两个 cmp 和 两个 je
在这里插入图片描述

||:两个 cmp 和 两个 jne
在这里插入图片描述

&: and
在这里插入图片描述

|:or
在这里插入图片描述

^: xor
在这里插入图片描述

~:not
在这里插入图片描述

==<< 和 >> ==: shl 和 sar

movzx:专门用来移动寄存器的低位(l)或高位(h)

在这里插入图片描述

分支语句

if: if 关键字并没有做什么特殊操作,真正发挥作用的还是 cmp 和 jne (由 == 号产生):
在这里插入图片描述else:jmp 保证执行了 if 就一定不会执行 else ,反之亦然:
在这里插入图片描述
switch:break 其实就是一个 jmp,另外有几个 case 就有几对 cmp ,je(对应了 != 号对应的汇编指令),switch 中的值会首先存入 eax 寄存器:
在这里插入图片描述

循环语句

for:首先初始化 i = 0,存入 基址寄存器(rbp) 中,然后用 cmp+jge(大于等于则跳转)判断是否要结束循环,如果不结束则使用 inc 让 i 自增:

jge:大于等于跳转
jg:大于跳转
jle:小于等于跳转
jl:小于跳转

在这里插入图片描述

while:基本一个套路,就是指令的顺序变化了一点
在这里插入图片描述

do while:do while 和 while/for 有不同之处,同样用高级语言做小于判断,do while 使用 cmp + jl,也就是说 while/for判断什么时候 “结束”,而 do while 则判断什么时候 “还可以运行”:
在这里插入图片描述

遍历数组:i 存入基地址寄存器 [rbp+0x34], 访问数组时,先将 i的值存入 rax 寄存器,然后使用 rax*4 的方式访问数组中的值(这里因为 int 类型所以是 *4 ,如果是char 数组则是 *1,以此类推…):
在这里插入图片描述

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
高级语言、汇编语言和机器语言是计算机编程中的三种不同的语言级别。 1. 高级语言高级语言是一种相对于机器语言和汇编语言而言的抽象层次更高的编程语言。它使用更接近自然语言的语法和结构,使得程序员能够更容易地编写和理解代码。高级语言的语法和命令格式因语言而异,如Java、C、C++、Python等。高级语言的代码需要通过编译器或解释器转换为机器语言或汇编语言才能被计算机执行。 2. 汇编语言: 汇编语言是一种介于高级语言和机器语言之间的低级语言。它使用助记符(mnemonic)来代替二进制指令,使得程序员能够更容易地理解和编写代码。汇编语言的指令直接对应于计算机硬件的指令,但是使用了更加可读的符号表示。汇编语言的代码需要通过汇编器将其转换为机器语言才能被计算机执行。 3. 机器语言: 机器语言是计算机能够直接执行的语言。它使用二进制代码表示指令和数据,每一条指令都是计算机硬件可以直接识别和执行的。机器语言的代码是由计算机硬件直接执行的,不需要经过编译或解释。 总结: 高级语言是相对抽象的编程语言,使用更接近自然语言的语法和结构;汇编语言是介于高级语言和机器语言之间的低级语言,使用助记符代替二进制指令;机器语言是计算机硬件直接执行的二进制代码。高级语言和汇编语言需要通过编译器或汇编器转换为机器语言才能被计算机执行。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值