101 - Lecture 11

news2024/10/22 6:14:13

课程概述

•	汇编语言中的输出(Output in inline assembly)
•	汇编语言中的输入(Input in inline assembly)
•	printf 函数的更多细节
•	scanf 函数的更多细节
•	程序流程控制(Controlling program flow)
•	跳转指令(Jumps)
•	无条件跳转(Unconditional jumps)
•	有条件跳转(Conditional jumps)

1. 汇编语言中的输出

Output in inline assembly
• 在C语言中声明变量后,汇编语言可以通过以下方式调用printf输出

声明字符串: char format[] = "Hello World\n";,用于存储需要输出的字符串。
lea eax, format   // 将字符串 'format' 的**地址**加载(load)到 eax 中
push eax          // 将字符串地址压入栈中(address of string, stack parameter)
call printf       // 调用 printf 库函数(use library code subroutine)
add esp, 4        // 清理栈上4字节的参数(clean 4 byte parameter off stack)

等效的C代码为:printf(“Hello World\n”);

输出数字的示例:

•	通过汇编调用printf输出整数:

声明格式字符串:声明格式化字符串 char format[] = “%d\n”;,用于指定printf以十进制的形式输出整数。
声明整数变量:声明一个整数变量 int myint = 157;,用于存储要输出的值。

push myint         // 将**变量的值**压入栈中
lea eax, format    // 将格式字符串的地址加载到 eax 中(address of the format string is saved in max)
push eax           // 将**格式字符串地址**压入栈中
call printf        // 调用 printf 函数(it will take two parameters from the stack)
add esp, 8         // 清理栈上两个参数的位置(clean up top two position in the stack)

在C语言中的等效代码为:printf(“%d”, myint);

Qualifier(限定词/修饰符) “%d” means the content of ‘myint’ will be printed as a decimal integer(十进制整数)

• scanf的作用是接收用户输入并存储在指定的变量中。因此,scanf不仅需要知道你希望存储数据的位置,还需要有权限去修改该变量的值。为了实现这一点,scanf需要获取变量的地址,从而能够直接修改变量的内容。
如果我们仅仅将变量的值压入栈中,scanf就无法知道应当在哪里存储输入的数据。因此,我们需要将变量的地址(而不是变量的值)压入栈中,以便scanf能够根据地址找到相应的内存位置来存储用户输入的值。

汇编语言中调用 printf 输出整数时的步骤。

  1. 压入第二个参数:Push the second parameter(integer variable to the stack)

    • 首先,将第二个参数(即要输出的整数值)压入栈中。因为 printf 需要先接收到数据才能进行输出,所以整数值作为输出的参数需要首先压入栈中。

  2. 压入第一个参数:push the first parameter(actually, address of the string)to the stack

    • 接着,将第一个参数压入栈中。在这里,第一个参数实际上是格式化字符串(如"%d"),它告诉 printf 应该如何处理输出的值。因此,压入的并不是格式字符串的内容,而是格式字符串的地址。

  3. 调用 printf 函数:call printf routine

    • 之后,调用 printf 函数。此时 printf 函数从栈中获取刚刚压入的两个参数:第一个是格式化字符串,第二个是要输出的整数。

  4. 清理栈:clean up top two positions in the stack

    • 最后,清理栈顶的两个位置。由于刚刚压入了两个参数,在调用 printf 之后,这两个参数仍然在栈中,所以需要将这两个参数从栈中移除,以确保栈处于干净状态,防止内存泄漏或混乱。

2. 汇编语言中的输入

Input in inline assembly
call to the standard C library routine: scanf(“%d”,&input);

• &input presents the address of the variable ‘input’

使用scanf读取用户输入并存储到变量中:

char format[] = "%d";//声明格式化字符串,用于指定 scanf 以十进制整数的格式读取用户输入。
int input;//声明一个整数变量 input,用于存储用户输入的数据。

lea eax, input     // 将变量 input 的地址加载到 eax 中
push eax           // 将变量地址压入栈中
lea eax, format    // 将格式字符串的地址加载到 eax 中(adress of the format string is saved in eax)
push eax           // 将格式字符串地址压入栈中
call scanf         // 调用 scanf 函数
add esp, 8         // 清理栈上两个参数的位置(clean top two position in the stack)

_asm 是 inline assembly(内联汇编)的缩写,用于在 C 语言代码中插入汇编语言指令。
这里,input是用于存储用户输入的整数变量,format表示格式化字符串"%d",用于读取整数。

3. More about printf和scanf

printf的类型修饰符(qualifiers)
• %c:输出字符(character)
• %d或%i:输出有符号的十进制整数(a signed decimal number)
• %s:输出字符串(a string of characters)
scanf的类型修饰符(qualifiers)
• %c:读取一个字符(a single character)
• %d:读取一个有符号的十进制整数
• %s:读取一个字符串,直到遇到空格、换行或终止符(a string of characters until a white space or terminator(blank, new line, tab)is found)

4. 程序流程控制

Controlling program flow
very few programs execute all instructions sequentially,from the first till the last one.Usually,one needs to control the flow of the program.
• 很少有程序从头到尾按顺序执行所有指令,通常需要跳转或循环:
• 根据条件从一个位置跳转到另一个位置。
• 当某个条件(condition)满足或直到某个条件达到时重复操作(repeat some action)。
• 通过调用和返回控制程序流程。(Passing control to and from procedures)

Jumps

跳转指令分类:
“跳转”是改变程序控制流(program control)从一个位置到另一个位置的最直接(straightforward)的方法
无条件跳转:(Unconditional)
• JMP指令无条件地将控制转移到另一条指令。
• 语法:JMP <目标指令的地址>
Syntax:JMP<address of the target instruction>
•目标指令的位置可以通过它的标签(label)来指定

标签通常是一个符号名称,用来标识代码中的一个位置,使得在程序的其他地方可以通过引用这个标签来跳转到这个位置执行代码

有条件跳转:(Conditional)
• 先测试条件,再根据条件决定跳转与否。
• 常见指令包括JCXZ和JECXZ,它们测试寄存器CX或ECX是否为零,其他跳转指令测试状态标志(status flags)。

5. 条件跳转指令

Jumping based on status flags

• 条件跳转指令根据状态标志的设置跳转(Jumping based on status flags),包括:
• JC / JB:如果进位标志设置(=1),则跳转。carry flag is set
• JNC / JNB:如果进位标志未设置(=0),则跳转。carry flag is clear
• JE / JZ:如果零标志设置(=1),则跳转。zero flag is set
• JNE / JNZ:如果零标志未设置(=0),则跳转。zero flag is clear
• JS:如果符号标志设置(=1),则跳转。sign flag is set
• JNS:如果符号标志未设置(=0),则跳转。sign flag is clear
• JO: Overflow flag is set (=1)
• JNO: Overflow flag is clear (=0)

Jumps Based on Comparison of Two Values

基于比较的跳转:

•	CMP指令最常用来测试条件跳转。它比较两个值并根据比较结果修改状态标志,而不改变比较的值。
•	常见条件跳转:
•	JE:第一个操作数等于第二个操作数时跳转。
•	JNE:第一个操作数不等于第二个操作数时跳转。
•	JG:第一个操作数大于第二个操作数时跳转。
•	JL:第一个操作数小于第二个操作数时跳转。

当执行 cmp eax, ebx 时,CPU 会将 eax 和 ebx 中的值进行减法操作(不改变这两个寄存器的值,只是隐式地进行减法),并根据减法结果设置状态标志。
• 如果 eax 和 ebx 的值相等:
• 零标志(Z) 将被设置为1(Z = 1),表示比较结果为零。
• 如果 eax 和 ebx 的值不相等:
• 零标志(Z)将被清除(Z = 0),表示比较结果不为零。

Example:
cmp ax, bx        ; 比较 AX 和 BX 的值
jg  label1        ; 如果 AX > BX,跳转到 label1
jl  label2        ; 如果 AX < BX,跳转到 label2
add ax, input     ; 将 input 的值加到 AX
cmp ax, 0         ; 比较 AX 和 0
jge label1        ; 如果 AX >= 0,跳转到 label1
jl  label2        ; 如果 AX < 0,跳转到 label2
  1. 示例问题解答

    • Q1: 在汇编代码中给printf传递两个参数时,第一个参数应该先压入栈中。(True or False)
    • 解答:False。调用printf时,应该先压入第二个参数,然后是第一个参数。
    • Q2: 在汇编中调用printf时,传递给它的参数将被printf从栈中弹出。(True or False)
    • 解答:True。printf会从栈中弹出传递给它的参数。
    • Q3: 在汇编中调用scanf时,需要将接收输入的变量地址压入栈中。(True or False)
    • 解答:True。scanf需要接收变量的地址才能将输入数据存储在该变量中。
    • Q4: 在printf中打印字符串时,使用的转换说明符是什么?
    • 解答:%s。
    • Q5: 如果在调用scanf时有三个整数参数被压入栈中,返回时如何调整寄存器esp的值?
    • 解答:需要将esp增加12,因为每个整数占4字节,三个整数总共12字节。
    • Q6: 执行cmp eax, ebx时会检查零标志的设置。(True or False)
    • 解答:True。cmp指令会根据比较结果设置零标志,如果eax和ebx相等,则设置零标志为1。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习 简易环境安装(不含Anaconda)

在Windows上安装深度学习环境而不使用Anaconda&#xff0c;下面是一个基于pip的安装指南&#xff1a; 1. 安装Python 确保你已经安装了Python。可以从Python官网下载Python&#xff0c;并在安装时勾选“Add Python to PATH”选项。 注意&#xff0c;Python 不要安装最新版的…

期权懂|期权止损策略如何平衡风险与收益?

本期让我懂 你就懂的期权懂带大家来了解&#xff0c;期权止损策略如何平衡风险与收益&#xff1f;有兴趣的朋友可以看一下。期权小懂每日分享期权知识&#xff0c;帮助期权新手及时有效地掌握即市趋势与新资讯&#xff01; 期权止损策略如何平衡风险与收益&#xff1f; 期权止损…

如何写一个视频编码器演示篇

先前写过《视频编码原理简介》&#xff0c;有朋友问光代码和文字不太真切&#xff0c;能否补充几张图片&#xff0c;今天我们演示一下&#xff1a; 这是第一帧画面&#xff1a;P1&#xff08;我们的参考帧&#xff09; 这是第二帧画面&#xff1a;P2&#xff08;需要编码的帧&…

计算机网络—静态路由

1.0 网络拓扑结构 星型拓扑结构是一个中心&#xff0c;多个分节点。它结构简单&#xff0c;连接方便&#xff0c;管理和维护都相对容易&#xff0c;而且扩展性强。网络延迟时间较小&#xff0c;传输误差低。中心无故障&#xff0c;一般网络没问题。中心故障&#xff0c;网络就出…

MIT-OC Electrochemical Energy Systems 1-2

一、等效电路模型 L2 电化学能量转换 1. 电化学能量转换与原电池 原电池可以将不同形式的能量&#xff08;化学能、太阳能、机械压力等&#xff09;转化为电能和热能。本文档讨论了一些原电池的示例及其等效电路模型。电压源&#xff1a;特性&#xff1a;电压源的特点是提供…

从网络请求到Excel:自动化数据抓取和保存的完整指南

背景介绍 在投资和财经领域&#xff0c;论坛一直是投资者们讨论和分享信息的重要平台&#xff0c;而东方财富股吧作为中国最大的财经论坛之一&#xff0c;聚集了大量投资者实时交流股票信息。对于投资者来说&#xff0c;自动化地采集这些发帖信息&#xff0c;并进行分析&#…

ionic Capacitor 生成 Android 应用

官方文档 https://ionic.nodejs.cn/developing/android/ https://capacitorjs.com/docs/getting-started 1、创建新的 Capacitor 应用程序 空目录下面 npm init capacitor/app2、install Capacitor npm install npm start在这里插入图片描述 3、生成dist目录 npm run buil…

ChatGPT 现已登陆 Windows 平台

今天&#xff0c;OpenAI 宣布其人工智能聊天机器人平台 ChatGPT 已开始预览专用 Windows 应用程序。OpenAI 表示&#xff0c;该应用目前仅适用于 ChatGPT Plus、Team、Enterprise 和 Edu 用户&#xff0c;是一个早期版本&#xff0c;将在今年晚些时候推出"完整体验"。…

二、PyCharm基本设置

PyCharm基本设置 前言一、设置中文汉化二、设置代码字体颜色三、设置鼠标滚轮调整字体大小四、修改 PyCharm 运行内存4.1 方式一4.1 方式二 五、显示 PyCharm 运行时内存六、设置代码模版配置的参数有&#xff1a; 七、PyCharm设置背景图总结 前言 为了让我们的 PyCharm 更好用…

Axure中继器实现时间读取和修改

亲爱的小伙伴&#xff0c;在您浏览之前&#xff0c;烦请关注一下&#xff0c;在此深表感谢&#xff01; 课程主题&#xff1a;中继器实现时间读取和修改 主要内容&#xff1a;中继器内不同时间格式的向外读取&#xff0c;和向内赋值&#xff0c;实现中继器时间的修改 应用场…

口电气设备:认证这道坎,如何跨越才能通全球?

今年国内各行各业都非常卷&#xff0c;出口成了一些公司的选择&#xff0c;但出口的电气设备往往不能跳过各种认证&#xff0c;这是市场准入的一部分&#xff0c;必须通过认证以满足当地的电气设备规范&#xff0c;比如出口欧盟需要CE认证 出口美国需要UL认证&#xff0c;加拿大…

ajax 读取文件

DOMException: Failed to read the responseXML property from XMLHttpRequest: The value is only accessible if the objects responseType is or document (was blob). at XMLHttpRequest.r ( $.ajax({ url: 未来之窗_服务, method: GET, …

展会亮点回顾|HMS汽车工业通信解决方案

2024 汽车测试及质量监控博览会&#xff08;中国&#xff09;&#xff08;Testing Expo China – Automotive&#xff09;于 8 月 28 日至 30 日在上海世博展览馆顺利举行。作为汽车测试技术领域的顶级盛会&#xff0c;来自全球的行业领袖和技术专家齐聚一堂&#xff0c;共同探…

基于Spring Boot、Vue和MyBatis的前后端分离座位管理系统:增删改查功能入门指南

在项目开发和工作实践中&#xff0c;创作灵感往往来自于对日常经验的总结与反思。通过记录技术难点和解决方案&#xff0c;不仅可以加深对问题的理解&#xff0c;还能为后续项目的优化提供参考。与此同时&#xff0c;撰写技术笔记、分享职场心得&#xff0c;不仅是对自己成长的…

Print Appearances Page 打印外观页面

Print Appearances 页面提供了设计时工具&#xff0c;用于自定义在打印网格控件时用于绘制 View 元素的外观。它提供对 BaseView.AppearancePrint 集合的设计时访问。此页面如下图所示。 当前在列表框中选择的 AppearanceObject 的外观设置在属性网格中列出。所有更改都会立即反…

OpenWRT 和 Padavan 路由器配置网络打印机 实现远程打印

本文首发于只抄博客&#xff0c;欢迎点击原文链接了解更多内容。 前言 之前有给大家介绍过 Armbian 安装 CUPS 作为打印服务器&#xff0c;像是 N1 盒子、玩客云&#xff0c;甚至是随身 WiFi 都可以通过 CUPS 来进行打印。但是有些朋友不想专门为打印机添置一个设备&#xff0…

前端实现鼠标可拖动弹框

目录 一、使用原生JS实现 1.HTML结构 2.CSS样式 3.使用JavaScript实现弹框的可拖动功能 二、使用Vue实现 分享一下前端常见功能“可拖动弹框”的实现方式&#xff0c;分别用原生JS和Vue实现。 一、使用原生JS实现 1.HTML结构 首先创建一个弹框的HTML结构&#xff0c;例如…

边缘计算网关助力煤矿安全远程监控系统

煤矿开采环境复杂&#xff0c;危险程度高&#xff0c;每一次事故都带给行业血淋淋的教训&#xff0c;安全问题也是政府与行业亟待解决的难题。伴随着技术的发展&#xff0c;煤矿智能化成为行业探索的新方向&#xff0c;降低安全风险也是智能化的重要目标之一。防微杜渐是安全生…

基于neo4j的体育运动员问答问答系统

你是不是也为毕业项目伤透了脑筋&#xff1f;我们为你准备了一个创新且实用的技术项目——基于neo4j的体育运动员问答系统。无论你是对图数据库技术感兴趣&#xff0c;还是想在自然语言处理方面有所突破&#xff0c;这套系统都能让你在答辩时脱颖而出&#xff01; &#x1f3a…

论文阅读——Restormer

项目地址&#xff1a; GitHub - swz30/Restormer: [CVPR 2022--Oral] Restormer: Efficient Transformer for High-Resolution Image Restoration. SOTA for motion deblurring, image deraining, denoising (Gaussian/real data), and defocus deblurring. 论文地址&#xf…