25考研计算机组成原理复习·4.3程序的机器级代码表示

2024-08-25 23:04

本文主要是介绍25考研计算机组成原理复习·4.3程序的机器级代码表示,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

高级语言与机器级代码之间的对应

常见的算术运算指令

常见的逻辑运算指令

AT&T格式 v.s. Intel格式

选择语句的机器级表示

无条件转移指令——jmp

条件转移指令——jxxx

示例:选择语句的机器级表示

循环语句的机器级表示

用条件转移指令实现循环

用loop指令实现循环

函数调用机器级表示

call、ret指令

如何访问栈帧?

访问栈帧数据:push、pop指令

访问栈帧数据:mov指令

如何切换栈帧?

栈帧内包含哪些内容?

参数、返回值传递

高级语言与机器级代码之间的对应

  • 指令的作用?1.改变程序执行流 2.处理数据
  • 指令格式:
    • 操作码:怎么处理?
    • 地址码:数据在哪儿?
      • 在寄存器里。在汇编指令中,给出寄存器名(通用寄存器:eax、ebx、ecx、edx;变址寄存器:esi、edi;堆栈寄存器:ebp、esp
      • 在主存里:在汇编指令中,给出读写长度主存地址dword ptr[地址] #32bitword ptr[地址] #16bittype ptr[地址] #8bit
      • 在指令里:在汇编指令中,直接给出常量,即“立即寻址”;可用十进制表示、也可用十六进制表示(通常用h结尾)

常见的算术运算指令

功能英文汇编指令注释
addadd d,s#计算d+s,结果存入d
subtractsub d,s#计算d-s,结果存入d
multiply

mul d,s

imul d,s

#无符号数d*s,乘积存入d

#有符号数d*s,乘积存入d

divide

div s

idiv s

#无符号数除法edx:eax/s,商存入eax,余数存入edx

#有符号数除法edx:eax/s,商存入eax,余数存入edx

取负数negativeneg d#将d取负数,结果存入d
自增++increaseinc d#将d++,结果存入d
自减--decreasedec d#将d- -,结果存入d

常见的逻辑运算指令

功能英文汇编指令注释
andand d,s#将d、s逐位相与,结果放回d
oror d,s#将d、s逐位相或,结果放回d
notnot d#将d逐位取反,结果放回d
异或exclusive orxor d,s#将d、s逐位异或,结果放回d
左移shift leftshl d,s#将d逻辑左移s位,结果放回d(通常s是常量)
右移shift rightshr d,s#将d逻辑右移s位,结果放回d(通常s是常量)

AT&T格式 v.s. Intel格式

AT&T格式Intel格式
目的操作数d、源操作数s

op s,d

注:源操作数在左,目的操作数在右

op d,s

注:源操作数在右,目的操作数在左

寄存器的表示

mov %ebx,%eax

注:寄存器名之前必须加“%”

mov eax,ebx

注:直接写寄存器名即可

立即数表示

mov $985,%eax

注:立即数之前必须加“$”

mov eax,985

注:直接写数字即可

主存地址表示

mov %eax,(af996h)

注:用“()”

mov [af996h],eax

注:用“[]”

读写长度表示

movb $5,(af996h)

movw $5,(af996h)

movl $5,(af996h)

addb $4,(af996h)

注:指令后加b、w、l分别表示读写长度为byte、word、dword

mov byte ptr[af996h],5

mov word ptr[af996h],5

mov dword ptr[af996h],5

add byte ptr[af996h],4

注:在主存地址前说明读写长度byte、word、dword

主存地址偏移量表示

movl -8(%ebx),%eax

注:偏移量(基址)

movl 4(%ebx,%eax,32),%eax

注:偏移量(基址,变址,比例因子)

mov eax,[ebx - 8]

注:[基址+偏移量]

mov eax,[ebx + eax*32 +4]

注:[基址+变址*比例因子+偏移量]

选择语句的机器级表示

无条件转移指令——jmp

mov eax,7
mov ebx,6
jum NEXT
mov ecx,ebx
NEXT: #用“标号”锚定位置 特征——有冒号,名字可以自己取
mov ecx,eax

条件转移指令——jxxx

cmp a,b #比较a和b两个数je<地址>  #jump when equal,若a=b则跳转
jne<地址>  #jump when not equal,若a!=b则跳转
jg<地址>  #jump when greater than,若a>b则跳转
jge<地址>  #jump when greater than or equal to,若a>=b则跳转
jl<地址>  #jump when less than,若a<b则跳转
jle<地址>  #jump when less than or equal to,若a<=b则跳转

示例:选择语句的机器级表示

if(a > b){c = a;
}else{c = b;
}
mov eax,7
mov ebx,6
cmp eax,ebx
jg NEXT
mov ecx,ebx
jum END
NEXT:
mov ecx,eax
END:

循环语句的机器级表示

用条件转移指令实现循环

int result = 0;
for(int i = 1;i <= 100;i++){result += i;
}//求1+2+3+…+100

用条件转移指令实现循环,需要4个部分构成:

  1. 循环前的初始化
  2. 是否直接跳过循环?
  3. 循环主题
  4. 是否继续循环?
mov eax,0  #1.用eax保存result,初值为0
mov edx,1  #1.用edx保存i,初始值为1
cmp edx,100  #2.比较i和100
jg L2  #2.若i>100,转跳到L2执行
L1:  #循环主体
add eax,edx  #3.实现 result += i
inc edx  #3.inc自增指令,实现i++
cmp edx,100  #4.i和100
jle L1  #4.若i <= 100,转跳到L1执行
L2:  #跳出循环主体

用loop指令实现循环

for(int i = 500;i > 0;i--){做某些处理;
}//循环500轮
mov ecx,500  #用ecx作为循环寄存器
Looptup:  #循环的开始
...
做某些处理
...
loop Looptop  #ecx--,若ecx!=0,跳转到Looptop
#等价于dec ecx 
#cmp ecx,0
#jne Looptop

理论上,能用loop指令实现的功能一定能用条件转移指令实现。

使用loop指令可能会使代码更清晰简洁。

补充:loopx指令——loopnz,loopz

        loopnz——当ecx≠0&&ZF==0时,继续循环

        loopz——当ecx≠0&&ZF==1时,继续循环

函数调用机器级表示

call、ret指令

  1. 函数调用指令:call<函数名>

    函数返回指令:ret

  2. call指令的作用:

    1. IP旧值压栈保存(保存在函数的栈帧顶部)(效果相当于 push IP)
    2. 设置IP新值,无条件转移至被调用函数的第一条指令(效果相当于jmp add)
  3. ret指令的作用:从函数的栈帧顶部找到IP旧值,将其出栈并恢复IP寄存器

如何访问栈帧?

栈帧(Stack Frame)保存函数大括号内定义的局部变量,保存函数调用相关信息

访问栈帧数据:push、pop指令

push、pop指令实现入栈、出栈操作,x86默认以4字节为单位。指令格式如下:

        push 🏇  //先让esp减4,再将🏇压入(🏇可以是立即数、寄存器、主存地址)

        pop 🐘  //栈顶元素出栈写入🐘,再让esp加4(🐘可以是寄存器、主存地址)

访问栈帧数据:mov指令

sub esp,12 #栈顶指针-12
mov[esp+8],eax  #将eax的值复制到主存[esp+8]
mov[esp+4],985  #将985复制到主存[esp+4]
mov eax,[ebp+8]  #将主存[ebp+8]的值复制到eax
mov [esp],eax  #将eax的值复制到主存[esp]
add esp,8  #栈顶指针+8

可以用mov指令,结合esp、ebp指针访问栈帧数据

可以用减法/加法指令,即sub/add修改栈顶指针esp的值

如何切换栈帧?

call指令的作用:

        将IP旧值压栈保存(效果相当于 push IP)

        设置IP新值,无条件转移至被调用函数的第一条指令(效果相当于jmp add)


push ebo #保存上一层函数的栈帧基址(ebp旧值)

mov ebp,esp #设置当前函数的栈帧基址(ebp新值)

 在每个函数开头的“例行处理”。两条指令等价于enter

mov esp,ebp #让esp指向当前栈帧的底部

pop ebp #将esp所指元素出栈,写入寄存器ebp

 在每个函数ret前的“例行处理”。两条指令等价于leave


ret指令的作用:从函数的栈帧顶部找到IP旧值,将其出栈并恢复IP寄存器

栈帧内包含哪些内容?

  1. gcc编译器将每个栈帧大小设置为16B的整数倍,因此战阵内可能出现空闲未使用的区域。
  2. 通常将局部变量集中存储在栈帧底部区域
  3. 通常将调用参数集中存储在栈帧顶部区域
  4. 栈帧最底部一定是上一层栈帧基址(ebp旧值)
  5. 栈帧最顶部一定是返回地址(当前函数的栈帧除外)

参数、返回值传递

  1. 在cal指令前,将调用参数写入栈帧顶部区域
  2. 在ret指令前,将函数返回值写入eax寄存器

这篇关于25考研计算机组成原理复习·4.3程序的机器级代码表示的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1106901

相关文章

ShardingProxy读写分离之原理、配置与实践过程

《ShardingProxy读写分离之原理、配置与实践过程》ShardingProxy是ApacheShardingSphere的数据库中间件,通过三层架构实现读写分离,解决高并发场景下数据库性能瓶... 目录一、ShardingProxy技术定位与读写分离核心价值1.1 技术定位1.2 读写分离核心价值二

深度解析Python中递归下降解析器的原理与实现

《深度解析Python中递归下降解析器的原理与实现》在编译器设计、配置文件处理和数据转换领域,递归下降解析器是最常用且最直观的解析技术,本文将详细介绍递归下降解析器的原理与实现,感兴趣的小伙伴可以跟随... 目录引言:解析器的核心价值一、递归下降解析器基础1.1 核心概念解析1.2 基本架构二、简单算术表达

深入浅出Spring中的@Autowired自动注入的工作原理及实践应用

《深入浅出Spring中的@Autowired自动注入的工作原理及实践应用》在Spring框架的学习旅程中,@Autowired无疑是一个高频出现却又让初学者头疼的注解,它看似简单,却蕴含着Sprin... 目录深入浅出Spring中的@Autowired:自动注入的奥秘什么是依赖注入?@Autowired

Redis实现高效内存管理的示例代码

《Redis实现高效内存管理的示例代码》Redis内存管理是其核心功能之一,为了高效地利用内存,Redis采用了多种技术和策略,如优化的数据结构、内存分配策略、内存回收、数据压缩等,下面就来详细的介绍... 目录1. 内存分配策略jemalloc 的使用2. 数据压缩和编码ziplist示例代码3. 优化的

从原理到实战解析Java Stream 的并行流性能优化

《从原理到实战解析JavaStream的并行流性能优化》本文给大家介绍JavaStream的并行流性能优化:从原理到实战的全攻略,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的... 目录一、并行流的核心原理与适用场景二、性能优化的核心策略1. 合理设置并行度:打破默认阈值2. 避免装箱

Python 基于http.server模块实现简单http服务的代码举例

《Python基于http.server模块实现简单http服务的代码举例》Pythonhttp.server模块通过继承BaseHTTPRequestHandler处理HTTP请求,使用Threa... 目录测试环境代码实现相关介绍模块简介类及相关函数简介参考链接测试环境win11专业版python

Python从Word文档中提取图片并生成PPT的操作代码

《Python从Word文档中提取图片并生成PPT的操作代码》在日常办公场景中,我们经常需要从Word文档中提取图片,并将这些图片整理到PowerPoint幻灯片中,手动完成这一任务既耗时又容易出错,... 目录引言背景与需求解决方案概述代码解析代码核心逻辑说明总结引言在日常办公场景中,我们经常需要从 W

使用Spring Cache本地缓存示例代码

《使用SpringCache本地缓存示例代码》缓存是提高应用程序性能的重要手段,通过将频繁访问的数据存储在内存中,可以减少数据库访问次数,从而加速数据读取,:本文主要介绍使用SpringCac... 目录一、Spring Cache简介核心特点:二、基础配置1. 添加依赖2. 启用缓存3. 缓存配置方案方案

MySQL的配置文件详解及实例代码

《MySQL的配置文件详解及实例代码》MySQL的配置文件是服务器运行的重要组成部分,用于设置服务器操作的各种参数,下面:本文主要介绍MySQL配置文件的相关资料,文中通过代码介绍的非常详细,需要... 目录前言一、配置文件结构1.[mysqld]2.[client]3.[mysql]4.[mysqldum

Python多线程实现大文件快速下载的代码实现

《Python多线程实现大文件快速下载的代码实现》在互联网时代,文件下载是日常操作之一,尤其是大文件,然而,网络条件不稳定或带宽有限时,下载速度会变得很慢,本文将介绍如何使用Python实现多线程下载... 目录引言一、多线程下载原理二、python实现多线程下载代码说明:三、实战案例四、注意事项五、总结引