汇编语言学习:使用masm32寻找1-100中的质数
最近有点自闭,事情贼多,还要学这么变态的汇编(╥╯^╰╥)。经过异常艰难的探索,终于完成了课程的第一个作业——用masm32寻找1-100的质数,写下此篇博客,转换一下心情。( • ̀ω•́ )✧
事先声明,我是汇编语言的萌新,接下来的代码可能存在许多多余和不合适的地方,而且我把所有的变量都存放在寄存器里面,这是极不合理的,在接下来的两次作业(斐波那契数列和八皇后问题)中我会加深对汇编的理解,改正代码中由于技术不足而出现的问题。
一. C语言参考程序
#include "stdio.h"
int main()
{for(int i=2;i<100;i++){bool flag = true;for(int j=2;j<i;j++){if(i%j==0){flag = false;break;}}if(flag){printf("%d ",i);}}
}
上述代码有几个地方需要强调:
(1)使用flag作为标志记录是否是一个质数。
(2)在判断是否除尽的时候我直接使用的条件是j<i而不是j<i/2是为了方便写汇编。
二. 环境
使用masm for windows作为编程工具,使用起来还是很方便的,也可以对汇编代码进行调试,个人觉得比使用VS要简洁一些。
三. 寄存器
AX,BX,CX,DX分别代表四个32位的寄存器。而AH,AL分别代表AX的高32位和低32位,BH,BL,CH,CL,DH,DL同理。
四. 常用指令
move AX,BX (将BX中的值放入AX中)
inc AX (将寄存器AX中的值加1)
jmp XXX (无条件跳转到XXX)
cmp AX,BX (比较AX,BX中的值是否相等)
je XXX (如果相等,则跳转到XXX)
push AX (把AX的值压入栈保护)
pop AX (把AX的值恢复)
add DL,BL (DL=DL+BL)
div操作复杂一些,为了取余,可以参考这篇博文汇编 DIV 指令
四. 整体思路
参照C语言代码的逻辑,分别用两个寄存器存储被除数和除数。外部的循环是被除数不断增加,直到100,判断其是否需要输出,内部循环是除数不断增加,直到被除数本身,遇到可以整除的即可判断其不是质数,便可以结束这个循环。当然,这个过程要变成一个直线化的过程才能写成汇编程序。
五. 难点
这个作业最大的难点竟然不是找质数,而是把找到的数字输出出来。使用了汇编才知道,有printf,cin,cout的日子是多么的幸福。
首先看到的是使用这样的命令进行输出:
mov DL,CH
mov AH,2
int 21H
将要输出的值写入DL寄存器,然后让ah为2,最后调用中断来输出,但是最开始这样做的时候只得到了一串奇怪的字符,查阅资料发现,这样输出的寄存器值对应的ASCII码,无法直接输出数字。
这对于从没有从底层考虑过问题的我确实非常难办,后来咨询了大佬,看了别人的源码才知道应该怎么处理这种情况:
(1)通过对寄存器的值进行调整,把其转化成对应的能输出数字的ASCII值,比如对于1,1+30h得到的就是对应的1的ASCII码,也就可以输出'1'了。
(2)但是这样只能输出一位,那对于多位数字应该怎么处理呢?很简单,取余。比如对于17,17/10 得1余7,7压入栈,1/10得0余1,结束循环,依次输出1和7,我们就得到了17.
六. 源码
DATAS SEGMENTDATAS ENDSSTACKS SEGMENT;此处输入堆栈段代码
STACKS ENDSCODES SEGMENTASSUME CS:CODES,DS:DATAS,SS:STACKS
START:mov BL, 2 ; save i(that is the dividend)mov BH, 2 ; save j(that is the divider)mov CL, 1 ; save flag(1 represent isPrime, 0 represent isNotPrime)
ISPRIME:cmp BL,100 ; check if need to end the programje STOP ; end the programcmp BL,BH ; check if divider reach to dividend iteselfje ISCANPRINT ; judge if can printXOR AX,AX ; empty AXMOV AL,BL ; move dividend to ALDIV BH ; AL%BH=AH remainder stored in AHcmp AH,0 ; Is there any exceptionje NOTPRIME ; if AH stores 0, that means the value stored in BL is not primeinc BH ; increase the dividerjmp ISPRIME ; turn to the beginning and loop
ISCANPRINT:cmp CL,1 ; check flagje PRINT ; print the valuemov BH,2 ; if not prime, divider begin again at 2 mov CL,1 ; reset flagjmp ISPRIME ; turn to the beginning and loop
PRINT:XOR BH,BH ; empty BHmov AX,BX ; move value to AXcall PRINTNUMBER ; print the numberNOTPRIME:inc BL ; increase dividendmov CL, 0 ; set flagjmp ISCANPRINT ; turn to judgePRINTNUMBER proc nearpush axpush bxpush cxpush dxmov bx,10mov cx,0PUSHTOSTACK:mov dx,0div bxpush dxinc cxcmp ax,0jz POPFROMSTACKjmp PUSHTOSTACKPOPFROMSTACK:pop dxadd dl,30h ; change ASCII to real numbermov ah,2 int 21hloop POPFROMSTACKpop dxpop cxpop bxpop axmov AH,2mov DL,0int 21hret
PRINTNUMBER endpSTOP: RET
CODES ENDSEND START
七. 参考资料
感谢各位大佬提供的源码,没有源码的学习,我不可能完成这次作业,掌握汇编的基本知识和解决一些难点。
https://github.com/LLipter/assembly/blob/master/Intel-16/primeNumber.asm
https://blog.csdn.net/bobo1356/article/details/51683904
汇编语言学习:使用masm32寻找1-100中的质数相关推荐
- 如何得到1-100中的质数
如何得到1–100中的质数 1. 明白什么是质数 ① 大于1的自然数 ② 只有两个因子,1和自身.也就是说只能被1和自身整除的数,就是质数. 2. 构建代码的框架 首先要随机生成一个1到100正整数组 ...
- windows下32位汇编语言学习笔记
windows下32位汇编语言学习笔记 第一章 第一章 背景知识 80x86处理器的存储器 4个数据寄存器 EAX,EBX,ECX,EDX EAX寄存器 所有API函数的返回值都保存在EAX里,注意 ...
- AM335X的汇编语言与c语言,X86汇编语言学习手记 -- 汇编和C协同
X86汇编语言学习手记(3) 2004年12月 在X86汇编语言学习手记(1)(2)中,可以看到栈(Stack)作为进程执行过程中数据的临时存储区域,通常包含如下几类数据: 局部变量 函数调用的返回地 ...
- Angel:深度学习在腾讯广告推荐系统中的实践
分享嘉宾:郭跃超 腾讯 应用研究员 编辑整理:康德芬 出品平台:DataFunTalk 导读:Angel是腾讯自研的分布式高性能的机器学习平台,支持机器学习.深度学习.图计算以及联邦学习等场景.Ang ...
- 黑暗危害:基于学习,大规模发现Android应用中的隐藏敏感操作(HSO)
黑暗危害:基于学习,大规模发现Android应用中的隐藏敏感操作(HSO) 摘要 隐藏敏感操作(HSO),例如:在接收SMS消息时窃取隐私用户数据正越来越多地被移动恶意软件和其他潜在危害应用(PHA) ...
- 深度学习新技术在搜狗搜索广告中的深化应用
大家好,我是来自搜狗搜索广告应用策略研究组的舒鹏,目前主要负责搜索广告算法研究工作,今天的题目是深度学习新技术在搜狗搜索广告中的深化应用.深度学习技术已经出现很多年,它在各个场景中都有应用,本次演讲的 ...
- win32汇编语言学习笔记(三)
汇编语言学习笔记(三) CH3.Windows汇编基础 .386 .model flat,stdcall option casemap:none 定义程序使用的指令集.工作模式 相应的还有:.8086 ...
- 【从零学习OpenCV 4】安装过程中问题解决方案
本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门 ...
- Symbian学习笔记(4)——在GUI应用中使用图像
今天学习一下如何修改GUI程序中的图标与如何加载图像. 与2nd.不同的是,3rd.支持svg格式的可缩放图标(最大好处在于一个图标搞定,以前用bmp时为了应用程序的菜单图标得要做四个小图标).而且, ...
最新文章
- 如何通过日期属性对数组进行排序
- httpservletrequest_javax.servlet.http.HttpServletRequest报错
- 将oracle冷备份恢复到另外一个数据库实例中
- java sendmessage_SendMessage()复制/剪切/粘贴WM_COPYDATA 0x004A
- MONGODB 权限认证
- PowerDesigner中的对象与关系映射建模
- Python 字典 values() 方法
- linux判断改行符_Linux判断符如何使用?
- YIi 设置 ajax 验证
- kali linux 数据源,kali Linux msf5 连接数据库 No database support
- 微博开放第三方协议 媒体机构能重掌话语权吗?
- 一个简单的网页抓取工具
- 零基础学python电子书-资料│最适合大学生零基础学的Python视频+电子书
- mockito无效_Mockito模拟无效方法
- DB2报错原因汇总(sqlcode sqlstate)
- IIS本地FTP服务器搭建
- 51单片机定时器中断
- filters 传参是什么_vue中filters 传入两个参数 / 使用两个filters的实现方法
- 19. 卫健委官网医院查询爬虫+验证码识别(云打码)综合案例
- 直播实录|百度大脑EasyDL·NVIDIA专场 部署专家
热门文章
- 呼叫中心系统成本及定价方式
- excel求平均值AVERAGE出现#DIV/0!
- 考研英语 长难句训练day91
- JavaScript 一元钱可以买一瓶水,两个空瓶可以换一瓶水,三个瓶盖可以换一瓶水,20块钱可以换多少瓶水。
- 【独立游戏体验计划】学习记录
- Robot Framework-DatabaseLibrary(MySql)
- 谷歌、Meta、英伟达……巨头扎堆的AIGC,国内发展如何了?
- Go语言安装第三方库
- JavaScript中的let是什么
- gcc 编译安装 configure-stage1-target-libgcc] Error 1