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

相关文章

将java程序打包成可执行文件的实现方式

《将java程序打包成可执行文件的实现方式》本文介绍了将Java程序打包成可执行文件的三种方法:手动打包(将编译后的代码及JRE运行环境一起打包),使用第三方打包工具(如Launch4j)和JDK自带... 目录1.问题提出2.如何将Java程序打包成可执行文件2.1将编译后的代码及jre运行环境一起打包2

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景

Python中顺序结构和循环结构示例代码

《Python中顺序结构和循环结构示例代码》:本文主要介绍Python中的条件语句和循环语句,条件语句用于根据条件执行不同的代码块,循环语句用于重复执行一段代码,文章还详细说明了range函数的使... 目录一、条件语句(1)条件语句的定义(2)条件语句的语法(a)单分支 if(b)双分支 if-else(

在不同系统间迁移Python程序的方法与教程

《在不同系统间迁移Python程序的方法与教程》本文介绍了几种将Windows上编写的Python程序迁移到Linux服务器上的方法,包括使用虚拟环境和依赖冻结、容器化技术(如Docker)、使用An... 目录使用虚拟环境和依赖冻结1. 创建虚拟环境2. 冻结依赖使用容器化技术(如 docker)1. 创

MySQL数据库函数之JSON_EXTRACT示例代码

《MySQL数据库函数之JSON_EXTRACT示例代码》:本文主要介绍MySQL数据库函数之JSON_EXTRACT的相关资料,JSON_EXTRACT()函数用于从JSON文档中提取值,支持对... 目录前言基本语法路径表达式示例示例 1: 提取简单值示例 2: 提取嵌套值示例 3: 提取数组中的值注意

CSS3中使用flex和grid实现等高元素布局的示例代码

《CSS3中使用flex和grid实现等高元素布局的示例代码》:本文主要介绍了使用CSS3中的Flexbox和Grid布局实现等高元素布局的方法,通过简单的两列实现、每行放置3列以及全部代码的展示,展示了这两种布局方式的实现细节和效果,详细内容请阅读本文,希望能对你有所帮助... 过往的实现方法是使用浮动加

JAVA调用Deepseek的api完成基本对话简单代码示例

《JAVA调用Deepseek的api完成基本对话简单代码示例》:本文主要介绍JAVA调用Deepseek的api完成基本对话的相关资料,文中详细讲解了如何获取DeepSeekAPI密钥、添加H... 获取API密钥首先,从DeepSeek平台获取API密钥,用于身份验证。添加HTTP客户端依赖使用Jav

Java实现状态模式的示例代码

《Java实现状态模式的示例代码》状态模式是一种行为型设计模式,允许对象根据其内部状态改变行为,本文主要介绍了Java实现状态模式的示例代码,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来... 目录一、简介1、定义2、状态模式的结构二、Java实现案例1、电灯开关状态案例2、番茄工作法状态案例