1611_PC汇编语言_math例程分析

news2024/11/20 7:21:11

         全部学习汇总: GreyZhang/g_unix: some basic learning about unix operating system. (github.com)

         这一次分析后带有注释的代码我会在笔记最后做一个完整的附加。

         这一个例程,主要是为了阐述前面讲到的数学运算。但是从这些操作中,很多底层的机理还是难以体会到的,比如说补码的用法。其实这些都是CPU设计中的一些事情了,我们只有在真正关注二进制信息的时候才会有所觉察。

         为了能够完成这个例程的编译链接,我修改了makefile,具体如上。相比上一次笔记中的makefile来说,差异点在行号位置也有所标注。其实,只是换了一个被编译链接的文件信息。

         这部分的设计,跟之前的first程序几乎一样,直接跳过。这也让人能够稍微有点成就感,毕竟前面的积累总归是发挥了作用。

         程序最开始的这部分子功能理解很容易,这时候寄存器涉及到的不多,而且其中的信息都是比较明确的。

         整理到这里,其实思路也还好。但是到了后面,寄存器的内容就有点混乱了。我觉得应该换一个思维模式来解读,那就是子功能段开始的时候先规划需要用几个寄存器,并且先考虑一个“寄存器内容初始化的动作”。

         比如,这一段功能其实是在前面的平方基础上乘以输入值。那么,我需要的一个输入是之前的平方结果,一个是输入值。由此,输入至少先需要2个寄存器(或者一个,另一个直接用存储)。做一下这个初始化,那就可以先寻找平方存放位置。这个其实是在eax之中。另外,需要输入值,可以存放在ebx之中。这跟原始的代码设计不同,但是我估计可以奏效。

         这是按照我自己的想法修改之后的程序,测试了一下的确是有相同的效果。

         按照上面的思路,其实这个地方的ebx换成eax应该也是相同的结果。实际的测试也是如此。这里出现的寄存器副本特别多,主要是因为几个函数在反复使用eax导致的。

         剩余部分的代码,其实也很容易理解。只是这里多了一个值得注意的除法操作,通过这个例子可以知道商和余数的存放位置规律。

增加注释后的代码:

;

; file: math.asm

; This program demonstrates how the integer multiplication and division

; instructions work.

;

; To create executable:

; nasm -f coff math.asm

; gcc -o math math.o driver.c asm_io.o

%include "asm_io.inc"

segment .data

;

; Output strings

;

prompt          db    "Enter a number: ", 0

square_msg      db    "Square of input is ", 0

cube_msg        db    "Cube of input is ", 0

cube25_msg      db    "Cube of input times 25 is ", 0

quot_msg        db    "Quotient of cube/100 is ", 0

rem_msg         db    "Remainder of cube/100 is ", 0

neg_msg         db    "The negation of the remainder is ", 0

segment .bss

input   resd 1

segment .text

        global  asm_main

asm_main:

        enter   0,0               ; setup routine

        pusha

        mov     eax, prompt

        call    print_string

        call    read_int

        mov     [input], eax

; 在此之前的部分与上一个first程序类似

; 对于读取的数值做一个有符号的自乘

        imul    eax               ; edx:eax = eax * eax

        ; 把结果转存到ebx,这样,后面的eax可以用来提供字符串打印功能

        mov     ebx, eax          ; save answer in ebx

        mov     eax, square_msg

        call    print_string

        ; 上面完成了字符串打印功能,把转存到ebx的结果搬运回来,调用函数打印

        mov     eax, ebx

        call    print_int

        call    print_nl

        ; 这一段的功能跟上面类似,只是乘法不再是自乘,而是乘以了一个指定的数值

        mov     ebx, eax

        imul    ebx, [input]      ; ebx *= [input]

        mov     eax, cube_msg

        call    print_string

        mov     eax, ebx

        call    print_int

        call    print_nl

        ;; 这一段的功能与上一段也是类似的,只是这里的乘数不再是指定的数值而是一个固定的数值。

        ;; 与此同时,imul的用法也发生了变化,目标参数有了修改

        imul    ecx, ebx, 25      ; ecx = ebx*25

        mov     eax, cube25_msg

        call    print_string

        ; 这是进行最终结果额度输出,还是进行了一次数值的搬运保证调用的函数奏效

        mov     eax, ecx

        call    print_int

        call    print_nl

        ; 这里的ebx数值来自于56行,也就是ebx乘以输入的数值。进一步,来自于55行的eax;再进

        ; 一步,来自于50行的ebx;再进一步来自46行的eax,也就是输入数值的平方乘以自身,即立方

        mov     eax, ebx

        ; eax转换成4字节,edx:eax

        cdq                       ; initialize edx by sign extension

        mov     ecx, 100          ; can't divide by immediate value

        ; 下面的除法运算的结果,商会在eax中存储,余数会存储在edx

        idiv    ecx               ; edx:eax / ecx

        ; 计算结果做一个存储

        mov     ecx, eax          ; save quotient into ecx

        mov     eax, quot_msg

        call    print_string

        mov     eax, ecx

        call    print_int

        call    print_nl

        mov     eax, rem_msg

        call    print_string

        mov     eax, edx

        call    print_int

        call    print_nl

        ; 这部分是一个取反操作

        neg     edx               ; negate the remainder

        mov     eax, neg_msg

        call    print_string

        mov     eax, edx

        call    print_int

        call    print_nl

        popa

        mov     eax, 0            ; return back to C

        leave

        ret

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

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

相关文章

介绍golang限流库以及漏桶与令牌桶的实现原理

RateLimit 限流中间件 前言 为什么需要限流中间件? 在大数据量高并发访问时,经常会出现服务或接口面对大量的请求而导致数据库崩溃的情况,甚至引发连锁反映导致整个系统崩溃。或者有人恶意攻击网站,大量的无用请求出现会导致缓…

Spark JDBC采用分区读取数据库时partitionColumn, lowerBound, upperBound, numPartitions参数理解

partitionColumn是应该用于确定分区的列。 lowerBound并upperBound确定要获取的值的范围。完整数据集将使用与以下查询对应的行: SELECT * FROM table WHERE partitionColumn BETWEEN lowerBound AND upperBound numPartitions确定要创建的分区数。lowerBound和之间…

Unicode 和 UTF-8 详解

结论 Unicode 是 字符集 UTF-8 是 编码规则 字符集:为每一个字符分配唯一的ID(如 SCII 码) 编码规则:将 码位转换为字节序列的规则 背景 老规矩,我们用图文并茂的方式来讲解: ASCII 这个字符集 由于仅能…

[Android Studio] Android Studio设置杂项

🟧🟨🟩🟦🟪 Android Debug🟧🟨🟩🟦🟪 Topic 发布安卓学习过程中遇到问题解决过程,希望我的解决方案可以对小伙伴们有帮助。 📋笔记目…

【HBase高级】3. HBase批量装载——Bulk load(1)Bulk load简介与案例介绍

2. HBase批量装载——Bulk load 2.1 简介 很多时候,我们需要将外部的数据导入到HBase集群中,例如:将一些历史的数据导入到HBase做备份。我们之前已经学习了HBase的Java API,通过put方式可以将数据写入到HBase中,我们…

MyBatis(三)使用MyBatis完成CRUD(增删改查)

准备工作 1、创建module(Maven的普通Java模块):mybatis-002-crud 2、pom.xml 打包方式jar依赖:mybatis依赖mysql驱动依赖junit依赖logback依赖3、mybatis-config.xml放在类的根路径下 4、CarMapper.xml放在类的根路径下 5、lo…

redis的完整学习

Redis 1.Nosql 单机mysql缓存机制分库分表水平拆分mysql集群:本质上是数据库的读写 MyISAM:表锁,效率低Innodb:行锁 特点 解耦! 1.方便扩展 2.大数据量高性能 3.数据类型是多样型的(不需要设计数据库&#xff…

c语言 预处理

int main() {//printf("%s\n", __FILE__);//打印所在文件夹位置//printf("%d\n", __LINE__);//打印当前所在行号//printf("%s\n", __DATE__);//打印当前系统日期//printf("%s\n", __TIME__);//时间//printf("%s\n", __FUNCT…

分享155个ASP源码,总有一款适合您

ASP源码 分享155个ASP源码,总有一款适合您 下面是文件的名字,我放了一些图片,文章里不是所有的图主要是放不下..., 154个ASP源码下载链接:https://pan.baidu.com/s/12oYeESSXJCd32n463LBt4w?pwd5i1n 提取码&#x…

Java线程池中的execute和submit

一、概述 execute和submit都是线程池中执行任务的方法。 execute是Executor接口中的方法 public interface Executor {void execute(Runnable command); }submit是ExecuteService接口中的方法。 public interface ExecutorService extends Executor {<T> Future<T…

vue+element模仿腾讯视频电影网站(二),增加视频播放详情页

一.前言 1. 本项目在线预览&#xff1a;点击访问 2. 作者其他博客成品汇总预览&#xff1a;点击访问 3. 接上一篇&#xff1a;《vueelement模仿腾讯视频电影网站》 暂时源码并没有提供其他获取渠道&#xff0c;私聊作者获取即可&#xff0c;或通过博客后面名片添加作者&#…

【SSM】Mybatis小技巧汇总

Mybatis技巧一&#xff1a;#{} 和 ${} 的区别使用 ${} 特例一&#xff08;排序&#xff09;使用 ${} 特例二&#xff08;表连接&#xff09;使用 ${} 特例三&#xff08;批量删除&#xff09;技巧二&#xff1a;typeAliases 别名机制别名 Alias 性质技巧三&#xff1a;mappersm…

串级PID控制原理-1

串级计算机控制系统的典型结构如图1所示&#xff0c;系统中有两个PID控制器&#xff0c;Gc2(s)称为副调节器传递函数&#xff0c;包围Gc2(s)的内环称为副回路。Gc1(s)称为主调节器传递函数&#xff0c;包围Gc1(s)的外环称为主回路。主调节器的输出控制量u1作为副回路的给定量R2…

Vuex基本概念

一、基本概念vuex&#xff1a;为了解决不关联的组件整个网站状态数据共享问题&#xff0c;专为Vue.js开发的状态管理模式。采用集中式存储管理应用的所有组件状态&#xff0c;并以相应的规则保证状态以一种可预测的方式发生变化。vuex有5个主要成员&#xff1a;state&#xff1…

DAMA数据管理知识体系指南之数据架构管理

第4章 4.1 简介 数据架构管理是定义和维护如下规范的过程&#xff1a; 提供标准的、通用的业务术语/辞典。 表达战略性的数据需求。 为满足如上需求&#xff0c;概述高层次的整合设计。 使企业战略和相关业务架构相一致。 数据架构是用于定义数据需求、指导对数据资产的整合和…

【C++】从0到1入门C++编程学习笔记 - 提高编程篇:STL常用容器(vector容器)

文章目录一、vector基本概念二、vector构造函数三、vector赋值操作四、vector容量和大小五、vector插入和删除六、vector数据存取七、vector互换容器八、vector预留空间一、vector基本概念 功能&#xff1a; vector数据结构和数组非常相似&#xff0c;也称为单端数组 vector…

Discord多账号抢白名单,如何避免账号关联被封号?

相信玩NFT项目的都不会对Discord陌生&#xff0c;现在NFT的项目都会开Discord伺服器&#xff0c;并且将内容公告在上面、在伺服器里互动&#xff0c;所以如果你想参与NFT的世界&#xff0c;学会使用Discord是一件非常重要的事情。 东哥前2天也出了关于discord如何使用、如何抢白…

很多网站、APP 前段时间一下都变灰了。 先来感受一下变灰后的效果。

很多网站、APP 前段时间一下都变灰了。 先来感受一下变灰后的效果。 这种灰色的效果怎么实现的呢&#xff1f;如何做到图片、文字、按钮都变灰的效果呢&#xff1f; 方案 1&#xff0c;换一套灰色的 UI&#xff0c;那显然成本太大了&#xff0c;用脚指头想一想就知道不太可能…

C语言---选择排序和堆排序

文章目录前言一、简单选择排序1.简介2.算法思路3.代码实现二、堆排序1.简介2.算法思路3.代码实现总结前言 堆排序是选择排序的一种&#xff0c;今天我们讲解一下堆排序和简单选择排序 一、简单选择排序 1.简介 选择排序&#xff08;Selection sort&#xff09;是一种简单直观…

ZoomCharts JavaScript 1.20.2 Crack

深入探索数据 令人惊叹的数据可视化方式 - 这里是 ZoomCharts JavaScript 图表的不同交互可能性和功能。 内容向下钻取和向上钻取 深入研究特定数据点或获得更大的图景。通过放大或缩小与图表进行物理交互&#xff0c;浏览不同的数据级别。 数据过滤 选择一个或多个数据点查看具…