1611_PC汇编语言_math例程分析

news/2024/10/31 3:19:41/

         全部学习汇总: 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.ppmy.cn/news/21376.html

相关文章

AXI 总线协议学习笔记(2)

引言 从本文开始,正式系统性学学习AXI总线。 如何获取官方协议标准? 第一步:登陆官网:armDeveloper 第二步:登录,无账号需要注册 第三步:点击文档 第四步: 第五步:浏…

BeanUtils源码解析

🍁 作者:知识浅谈,CSDN博客专家,阿里云签约博主,InfoQ签约博主,华为云云享专家,51CTO明日之星 📌 擅长领域:全栈工程师、爬虫、ACM算法 💒 公众号&#xff1a…

Axios网络请求

哈喽~大家好,这篇来看看Axios网络请求。 ​文章推荐链接SpringCloud Sentinel 使用SpringCloud Sentinel 使用将Nacos注册到springboot使用以及Feign实现服务调用将Nacos注册到springboot使用以及Feign实现服务调用微服务介绍与 SpringCloud Eureka微服务介绍与 Sp…

Java程序设计实验3 | 面向对象(上)

*本文是博主对Java各种实验的再整理与详解,除了代码部分和解析部分,一些题目还增加了拓展部分(⭐)。拓展部分不是实验报告中原有的内容,而是博主本人自己的补充,以方便大家额外学习、参考。 目录 一、实验…

OAuth2介绍

目录 一、什么是OAuth2 二、OAuth2中的角色 三、认证流程 四、令牌的特点 五、OAuth2授权方式 授权码 隐藏方式 密码方式 凭证方式 一、什么是OAuth2.0 概念:第三方授权解决方案 OAuth2.0是目前使用非常广泛的授权机制,用于授权第三方应用获取…

【Redis】.net core 3.1 Redis安装和简单使用

Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。 简单来说,就是一个键值对数据库。 Redis支持的…

【DataX】datax | datax-web | win搭建datax-web环境

一、环境准备 1、jdk8 2、maven 3、mysql7 4、python3 5、window10 6、idea 7、2345解压(win支持tar.gz解压) 8、git 二、操作步骤 1、datax操作步骤 1)下载datax http://datax-opensource.oss-cn-hangzhou.aliyuncs.com/datax.tar.gz 2&am…

maxcomputer的分区表相关操作

– 查看xsxw(学生行为表定义) desc xsxw; – 查看xsxw1(学生行为表定义) desc xsxw1; – 上面的两张表是通过ddl语句创建的分区表 – 创建ddl语句如下 – CREATE TABLE IF NOT EXISTS xsxw1( – xwsj STRING COMMENT ‘行为时间’, – xh STRING COMMENT ‘学号’, – xwdd ST…