80x86汇编—分支循环程序设计

文章目录

  • 查表法: 实现16进制数转ASCII码显示
  • 计算AX的绝对值
  • 判断有无实根
  • 地址表形成多分支
  • 从100,99,...,2,1倒序累加
  • 输入一个字符,然后输出它的二进制数
  • 大小写转换
    • 大写转小写
    • 小写转大写
  • 冒泡排序
  • 剔除空格

查表法: 实现16进制数转ASCII码显示

题目要求:
;查表法,实现十六进制数转换为ASCII码显示
;数据段
HEX db 4bh
ASCII db 30h,31h,32h,33h,34h,35h
db 36h,37h,38h,39h ;0~9的ASCII码
db 41h,42h,43h,44h,45h,46h
;A~F的ASCII码
;任意固定了一个待转换的一位16进制数

思路:首先题目要求的是一个固定的ASCII数据段作为表,然后也固定了一个HEX作为一个待转换的十六进制的数字。希望我们用字符形式将4b显示出来,所以我们可以将高4位和低4位分离出来,然后使用02中断号逐一显示
(02中断号:从dl中取出数值显示,每次显示一个字符,光标就会向右移动一个字符的位置,素有不会覆盖前一个字符)
注意事项:该4bh是一个8位十六进制数,占一个字节数,所以我们在分离的时候很容易错的一个点是,稍不注意就把8位的al使用了(不一定使用al可以是其他寄存器),其实我们还需要将al寄存器的前4位进行清空操作。其次很容易忽略的就是,我们02中断号显示的字符码数值都是从dl中取,所以在处理好的数据后,记得将处理好的数据存进dl中。最后,ah需要存中断号,所以记得将02h存进ah中。由于我们是高低4位需要两次调用,在第二次的调用02h中断号的时候我认为还是要重新将02h存进ah中,因为这样能保证中断号肯定是02h,在第二次调用之前不知道有没有影响到ah,所以我就再次mov ah, 02h,当然你觉得没有影响的话是可以不用重复的(啰嗦一下)。
我的代码肯定不是最优,可以自己去优化一下。

理论存在,开始实现!

运行结果:
在这里插入图片描述
代码实现:

;实现十六进制数转换为ASCII码显示
assume cs:codes, ds:datasdatas segment
HEX	db 4bh ;任意设定了一个待转换的一位16进制数
ASCII	db 30h,31h,32h,33h,34h,35hdb 36h,37h,38h,39h	;09的ASCII码db 41h,42h,43h,44h,45h,46h ;A~F的ASCII码
datas endscodes segmentstart:mov ax, datasmov ds, ax;思路:分割高低位,然后直接作为ASCII数据段的下标即可;使用02中断号显示,因为每次显示一个字符光标就会右移一位mov bx, offset ASCII;先显示高位的十六进制数字mov al, HEXmov cl, 4shr al, clxlatmov dl, almov ah, 02h int 21h;后显示低位的十六进制数字mov al, HEXand al, 0fhxlatmov dl, almov ah, 02hint 21h;结束代码段mov ax, 4c00hint 21hcodes ends
end start 

计算AX的绝对值

题目要求:计算AX的绝对值

这题没啥难度,就是基本的存数,取数,然后跳转。

运行结果:
在这里插入图片描述

细节:判断完负数后,如果不跳转的话下一条指令就是跳过负数操作的跳转语句。这一步是实现真正的if else语句的精华,当然如果你觉得你可以实现一次跳转的话当我没说。
在这里插入图片描述

代码实现:同时也使用了js,判断符号位是否为1即是否为负数的转移指令也是一样效果。

;计算AX的绝对值
assume cs:codes, ds:datas
datas segment
NUM db -5
Result db ?
datas ends codes segmentstart:mov ax, datasmov ds, axmov al, NUMcmp al, 0 ;直接跟0比较;是否跳转可以通过看SF标志位,这是有符号数字,所以我们单看CF是否进位是不行的,;当然可以用有符号的跳转指令,less和greater,这里我们都尝试一下jl nee ;小于就跳转;js nee ;SF符号位是1就表示负数,也要跳转,这个可以替换jl,等同效果;负数就取补码jnl none ;如果是正数需要跳过取补码的语句nee: neg al;正数绝对值是自己none: mov Result, al;结束代码段mov ax, 4c00hint 21h
codes ends
end start  
  • 优化:你还别说,还真有只用一个跳转就能实现取绝对值

其实我们只要反其道而行,判断是否不是负数,也就是说先判断是否是正数,正数就跳转直接存结果,这里通过跳转跳过了一条取补码的语句,所以说当不是正数的时候就会不跳转,直接执行取补码语句,然后自动执行原本就要执行的存结果。如下图所示

运行结果:
在这里插入图片描述
代码实现:

;计算AX的绝对值优化版本
assume cs:codes, ds:datas
datas segment
NUM db -5
Result db ?
datas endscodes segmentstart:mov ax, datasmov ds, axmov al, NUMcmp al, 0 ;直接跟0比较;是否跳转可以通过看SF标志位,这是有符号数字,所以我们单看CF是否进位是不行的,;当然可以用有符号的跳转指令,less和greater,这里我们都尝试一下jnl none ;如果不是小于就直接存结果,因为正数绝对值是自己;jns none ;同理这个判断SF不等于1即SF=0为正数就跳转,否则就执行下面取补码neg al ;上面没有跳转就属于小于,就是负数,自动来到这里取补码none: mov Result, al ;结束代码段mov ax, 4c00hint 21h
codes ends
end start 

判断有无实根

题目要求:判断有无十根,就是判断有无解
首先判断公式就是:b2 - 4ac >= 0 的话就有解

细节:我这里的4 *ac我使用的是ac结果左移两位,当然可以使用传统的imul乘4操作,基本没啥细节可讲。

运行结果:
在这里插入图片描述
代码实现:

;判断有无实根
assume cs:codes, ds:datas
datas segment
_b db 4
_a db 2
_c db 2
;4*4 - 4*2*2 = 0 tag db 9 ;默认数值是9, 通过程序运行后,有解为1  无解为0
datas ends
codes segmentstart:mov ax, datasmov ds, ax;计算b²mov al, _bimul al ;al * al = ax = b²mov dx, ax;计算4acmov al, _aimul _cmov cl, 2shl ax, cl ;左移两位即乘4,即4 * ac;开始比较b² - 4ac是否大于等于0,即是否有解cmp dx, axjae yes ;有解就跳;无解就不跳来到这里赋值完再跳到结束mov tag, 0 jmp doneyes: mov tag, 1 ;有解,且下一条代码就是结束了,所以不用继续跳;代码段结束done:mov ax, 4c00hint 21h
codes ends
end start

地址表形成多分支

题目要求:
需要在数据段事先安排一个按顺序排列的转移地址表
输入的数字作为偏移量。因为只有2个字节16位偏移地址,所以偏移量需要乘2
注意:这里的地址表是在前头,然后我们disp这些我把他写在了代码段最后面。不用担心未定义,因为在汇编里面的标号翻译成地址都是汇编编译器做的。
在这里插入图片描述

细节:最重要的就是题目已经提醒过了,很显然我在做的过程中还是把他忘记了,因为只有2个字节16位偏移地址,所以偏移量需要乘2,这就是我哦们table[bx]用bx查找表的时候需要记得将地址乘以2,因为一个元素就占两个位置,在汇编中就是这样,我们8086是以字节为单位,这里的table一个地址元素就是dw字型,所以我们要乘以2!乘以2!乘以2!,更多细节我都写在代码注释里面了,不明白为什么有的人写代码会忍得住不写注释。。。
其他没啥好注意的,这个代码敲起来还是比较爽的,分支结构越来越像我们高级语言了,实现的时候简直不要太优雅~

在这里插入图片描述
代码实现:

;table是一个标号入口表,
;这些标号都在程序后面,
;每一个标号对应将msg_num的IP地址存入dx然后使用中断号09显示assume cs:codes, ds:datas
datas segmentmsg		db 'Input number(1~8):',0dh, 0ah, '$'
msg1	db 'Chapter 1 : ...'   ,0dh, 0ah, '$'
msg2	db 'Chapter 2 : ...'   ,0dh, 0ah, '$'
msg3	db 'Chapter 3 : ...'   ,0dh, 0ah, '$'
msg4	db 'Chapter 4 : ...'   ,0dh, 0ah, '$'
msg5	db 'Chapter 5 : ...'   ,0dh, 0ah, '$'
msg6	db 'Chapter 6 : ...'   ,0dh, 0ah, '$'
msg7	db 'Chapter 7 : ...'   ,0dh, 0ah, '$'
msg8	db 'Chapter 8 : ...'   ,0dh, 0ah, '$'table	dw disp1,disp2,disp3,disp4  ;取得各个标号的偏移地址dw disp5,disp6,disp7,disp8datas endscodes segment start:;常规修改段地址mov ax, datasmov ds, ax ;准备工作,打印提示用户输入数字mov dx, offset msgmov ah, 09hint 21h;等待用户输入一个字符,这就需要用到01中断号,;刚好是等待一个按键按下,输入的数据送到al中mov ah, 01hint 21h;首先判断是否是1-8之间的数字cmp al, '1';如果小于1就重新输入jb start;如果大于8就重新输入cmp al, '8'ja start ;开始找table表然后打印字符串;获取al中的字符ascii数,并将其转化为对应的数值and ax, 000fh ;这是种常见的转换数值,;因为ascii转为二进制的时候,;低四位是对应的顺序012345;同样的字母也是,;应该说字母a-z,A-Z不论大小写,;还有0-9都是可以只保留低4位来指明第几个dec ax ;因为输入的数字是1-9,但是下标是从0开始的,所以要减一;由table是dw类型,所以需要找到对应的地址还需要地址转换shl ax, 1mov bx, ax ;先乘以2,即移位两位,然后存入bx中;跳转jmp table[bx] ;通过table找到对应的入口地址showString: ;开始显示找好的字符串,;使用09h中断号,ds:dx作为字符串参数入口;因为字符串后面有$作为结束符mov ah, 09hint 21h;结束代码段mov ax, 4c00h;int 21h
disp1:mov dx, offset msg1jmp showStringdisp2:mov dx, offset msg2jmp showString
disp3:mov dx, offset msg3jmp showString
disp4:mov dx, offset msg4jmp showString
disp5:mov dx, offset msg5jmp showString
disp6:mov dx, offset msg6jmp showString
disp7:mov dx, offset msg7jmp showString
disp8:mov dx, offset msg8jmp showString
codes ends
end start 

从100,99,…,2,1倒序累加

题目要求:将100…1相加,然后存到一个sum中

细节:我们的目的操作数是内存的时候,该运算是多少位的就要看源寄存器位置位数是多少,我们这个sum最后用8位二进制位肯定装不下,所以我们要控制他进行运算的位数是16位,所以一定要将源操作数位置中使用16位的寄存器。

在这里插入图片描述
代码实现:

;100,99,...,2,1倒序累加
assume cs:codes, ds:datas
datas segment
sum dw 0
datas ends
codes segmentstart:mov ax, datasmov ds, axmov cx, 100s:add sum, cx;由于sum是内存,所以决定运算位数的是源操作数,;因此一定要用cx,不能用cl,否则会变成8位运算装不下的情况loop s;代码段结束mov ax, 4c00hint 21hcodes ends
end start

输入一个字符,然后输出它的二进制数

题目要求:你输入一个字符,然后需要你将这一个字符的ascii码的二进制数以字符的形式显示出来。

细节:记得将存在al的字符取出来。其次,需要使用adc将左移出去存在CF中的位加进去。
在这里插入图片描述

代码实现:

;输入一个字符,然后输出它的二进制数
assume cs:codes
codes segmentstart:;录入一个字符,然后字符存入al中mov ah, 01hint 21hmov bl, al;输出一个:作为分隔符,使用02中断,;dl是输出的字符,并且右移一位mov dl, ':'mov ah, 02hint 21hmov cx, 8s:shl bl, 1 ;移除的位存进CF中,可以使用adc加进去mov dl, 0 ;清空dl再相加adc dl, 30h;因为要显示字符01,所以我们加上30hint 21hloop s;代码段结束mov ax, 4c00hint 21hcodes ends
end start 

大小写转换

大写转小写

题目要求:
将字符串中,碰到有大写的字符转为小写字符
不需要操作小写字符
碰到结尾符为0就结束

细节:小写字母中,二进制的从第0位开始数到第五位是1的就是小写字母字符的ascii,强制转小写就是:ax = ‘A’ 的时候 那就or ax , 00100000B

实现大写转小写的运行结果:
在这里插入图片描述

代码实现:

;将字符串中,碰到有大写的字符转为小写字符
;不需要操作小写字符
;碰到结尾符为0就结束
assume cs:codes, ds:datasdatas segment
string db "aBCDeFghIJkL"db 0
datas endscodes segment start:mov ax, datasmov ds, axmov di, 0again:mov bl, string[di]or bl, bl ;判断是否为0了,是的话就结束jz done ;由于不需要操作小写字符,就要判断是否是大写范围内cmp bl, 'Z'  ;这里先判断是否大于Z,如果是大于的话肯定是小写;假设我们先判断A的话,每次进来的是小写,小写字符肯定大于Aja next ;是否大于Z,是就不用转换cmp bl, 'A'jb next ;是否小于A,是就不用转换or bl, 20h ;字母的ascii中二进制数中的第五位为1 , 那就是小写  mov string[di], bl ;需要将转换好的字符存回去next:inc dijmp againdone:mov ax, 4c00hint 21hcodes ends
end start 

小写转大写

同理,逻辑差不多,修改一下跳转指令和转换操作修改即可。
大写字母中,二进制的从第0位开始数到第五位是0的就是大写字母字符的ascii,强制转大写就是:ax = ‘a’ 的时候 那就and ax , 11011111B

实现大写转小写的运行结果:
在这里插入图片描述
代码实现:


assume cs:codes, ds:datasdatas segment
string db "aBCDeFghIJkL"db 0
datas endscodes segment start:mov ax, datasmov ds, axmov di, 0again:mov bl, string[di]or bl, bl ;判断是否为0了,是的话就结束jz done cmp bl, 'a'jb next ;是否小于A,是就不用转换cmp bl, 'z'  ja next ;是否大于Z,是就不用转换and bl, 0dfh ;字母的ascii中二进制数中的第五位为0 , 那就是大写mov string[di], bl ;需要将转换好的字符存回去next:inc dijmp againdone:mov ax, 4c00hint 21hcodes ends
end start 

冒泡排序

题目要求:
将下面这段数据从小到大排序,使用冒泡排序
datas segment
list db 32, 85, 16, 15, 8
datas ends

既然学汇编了,那必然不是什么小人物了,所以冒泡就不介绍了。
细节:我们的list是db类型,记得使用8位寄存器来交换,否则会连累到后面的数据。 别问我为什么知道会这样
在这里插入图片描述
代码实现:

assume cs:codes, ds:datasdatas segment list db 32, 85, 16, 15, 8
datas endscodes segmentstart:mov ax, datasmov ds, ax;精华就是内循环次数和剩余的外循环次数每次都是一样的mov cx, 5dec cx mov dx, cxmov bx, 0outer:inner:mov al, [bx]cmp al, [bx + 1]jle next ;如果小于等于就直接跳过不交换xchg al, [bx + 1]mov [bx], alnext:inc bxcmp bx, dxjl inner ;小于就继续,大于等于就退出mov bx, 0dec dxloop outer;代码段结束mov ax, 4c00hint 21hcodes ends
end start 

剔除空格

题目要求:
现有一个以$结尾的字符串,要求剔除其中的空格
assume cs:codes, ds:datas
datas segment
string db ‘Let us have a try !’, ‘$’
datas ends

细节:还是别忘记了字符是db,所以交换的时候记得用8位寄存器。其次我们最后的
mov al, [di-1]
cmp al, ' ′ 这两句差点把我搞崩了, d i − 1 这里需要 − 1 是因为我在之前 i n c d i 了,所以如果要找到原本的字符就要 ' 这两句差点把我搞崩了,di-1这里需要-1是因为我在之前inc di了,所以如果要找到原本的字符就要 这两句差点把我搞崩了,di1这里需要1是因为我在之前incdi了,所以如果要找到原本的字符就要,否则当你到最后的时候,由于inc di,下标过了$字符,那就永远跳不出循环了,
然后就是cmd控制台直接给你卡住…

在这里插入图片描述

;现有一个以$结尾的字符串,要求剔除其中的空格
assume cs:codes, ds:datas
datas segmentstring db 'Let us have a try !', '$'
datas endscodes segmentstart:mov ax, datasmov ds, axmov si, 0;使用最烂的方法,每碰到一次空格就全部向前移动一次mov al, string[si]outer:cmp al, ' 'jnz next ;不是空格就下一个字符mov di, siinner: ;如果是字符就进行移位xchg al, [di+1]mov [di], alinc dimov al, [di-1]cmp al, '$'jnz inner ;如果不是$就继续next:inc simov al, string[si]cmp al, '$'jnz outer ;如果不是$就继续;代码段结束mov ax, 4c00hint 21hcodes ends
end start 

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

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

相关文章

织梦服务器系统win10,WIN服务器爆破DEDECMS后台目录

利用脚本python:#!/usr/bin/env python/** author Mochazz* team 红日安全团队* env pyton3**/import requestsimport itertoolscharacters "abcdefghijklmnopqrstuvwxyz0123456789_!#"back_dir ""flag 0url "http://192.168.1.9/t…

人工智能技术对专利制度的挑战与应对

来源:上海市法学会内容摘要人工智能技术作为人类的一项发明创造,本身具备了一定的创造力。无论是专利法治实践还是理论研究均无法否认,在弱人工智能时代,人工智能技术兼具发明创造工具和发明创造方案的提供者的双重身份。由此导致…

网络推广恶意点击js_做好网络推广,是做好网络营销的必要条件

互联网社会里网络无处不在,商机无处不在,企业通过网络营销,能有效的避免线下竞争激烈的市场,做好网络推广,是做好网络营销的必要条件。一个优秀的网络推广团队不但能实现提高企业的知名度的目的,还能帮助企…

css盒子模型_css的盒子模型是什么

CSS盒子模型就是在网页设计中经常用到的CSS技术所使用的一种思维模型。css盒子模型又称为框模型 (Box Model) ,包含了元素内容(content)、内边距(padding)、边框(border)、外边距(margin)几个要素组成了盒子模型。图中最内部的框是元素的实际内容,也就是…

6G应用场景有哪些?首份6G报告给你揭晓

来源: 5G产业圈导 读中国移动研究院无线与终端技术研究所所长丁海煜介绍称,按照移动通信产业“使用一代、建设一代、研发一代”的发展节奏,业界预期6G将于2030年左右实现商用。“创新、协调、绿色、开放、共享”应成为5G向6G演进的新发展理念…

linux python 图形界面开发_python在linux制作图形界面(snack)

snack是一个用于在linux制作图形界面(GUI)的模块,该模块由c编写,而且redhat的系统都自带这个模块。 1.获取模块 虽然redhat系统会自带这个模块,但是直接去import snack会提示找不到模块,一个原因是我们重装…

虚拟搭建局域网模拟器_巧用虚拟局域网,快速搭建私有云,一步就能搞定

前段时间公司一直在使用局域网来进行文件共享,用一台电脑把某个文件夹在局域网里共享出来,其他电脑远程访问,但是这样使用太麻烦,要是主电脑忘记开机,其它人就用不了。再就是,一旦离开公司之后,…

5个层级带你看清一颗芯片的内部结构

来源:北京物联网智能技术应用协会导 读在我们阐明半导体芯片之前,我们先应该了解两点。其一半导体是什么,其二芯片是什么。

python使用shell命令_python 调用shell命令的方法

在python程序中调用shell命令,是件很酷且常用的事情…… 1. os.system(command) 此函数会启动子进程,在子进程中执行command,并返回command命令执行完毕后的退出状态,如果command有执行内容,会在标准输出显示。这实际上…

java中必检异常有哪些_Java面试题经典面试题220道(附答案)

Java基础:1.JDK 和 JRE 有什么区别?2. 和 equals 的区别是什么? 解读3. 两个对象的 hashCode() 相同, 那么 equals() 也一定为 true吗?4. final 在 Java 中有什么作用?5. Java 中的 Math. round(-1. 5) 等…

11项关键先进制造技术解读!

来源:中国指挥与控制学会图片:来源于网络上届美国总统奥巴马非常重视制造业。其发起成立的“先进制造业合作委员会”,Advanced Manufacturing Partnership,就未来制造业的发展做出了展望,重点规划11个技术领域&#xf…

网站程序数据库怎么上传到服务器上,网站的数据库怎么上传到服务器

网站的数据库怎么上传到服务器 内容精选换一换通常在将数据导入数据库前,即将入库的数据已经在相关主机上了。我们称这种保存着待入库数据的服务器为数据服务器。此时,只需检测以确认数据服务器和GaussDB(for openGauss)集群能够正常通信,并查…

知道接口地址 如何传数据_数据不知道如何可视化?一款工具推荐给大家

之前我们介绍过 Python 里面的一些数据分析和可视化工具,比如 Pandas、Modin、Dash 等。今天要介绍一款标星 12.1K 的数据可视化工具 bokeh,优雅、简洁、高性能的交互式可视化库,同时支持大数据量和流式数据。其中 PyPI 和 Conda 每月安装超过…

c# 从一组数中随机抽取一定个数_Python随机模块22个函数详解

随机数可以用于数学,游戏,安全等领域中,还经常被嵌入到算法中,用以提高算法效率,并提高程序的安全性。平时数据分析各种分布的数据构造也会用到。random模块,用于生成伪随机数,之所以称之为伪随…

读书人:人机融合中的深度态势感知

雅典学院(拉斐尔)来源:人机与认知实验室“你现在的气质里,藏着你走过的路,读过的书和爱过的人。"— 电影《卡萨布兰卡》里的一句话《追问人工智能》--刘伟 - 读书人视频如下:https://www.bilibili.com…

根据id 隐藏_明星ID价值四位数?吃鸡玩家崩溃:打工一个月工资还没名称值钱...

01你知道吗?和平精英游戏名称也很值钱?——最近,有这样一条消息出现在了我的面前,某和平精英角色明星名称的价格居然被捧到了千元之上,对,各位没有看错,虽然只是一个普普通通的游戏名称&#xf…

范式变革与规律涌现:世界科技发展新趋势

来源:学习时报新科技革命与产业变革持续展开,以人工智能为代表的新兴使能技术驶入“快车道”,世界科技创新被认为正在进入“认知革命”的阶段——对生命过程的“精微刻画与操作”和对人类智能的“逆向工程与强化”。趋势特征从“大停滞”迈向…

Unity5和WebGL移植指南的一些总结

对于手游开发者来说,更新版本往往意味着非常复杂的过程,你需要根据反馈做更新、测试、提交然后等待审核,而由于不需要客户端依赖,页游往往是快速测试游戏版本的最佳途径,很多人可能都知道Unity 5可以再不用Unity Web P…

java indexof方法_【3-14】Java中集合类list的增删改查

Hello,大家好,我是大家最亲爱的siki老师,每天都会在这里为大家带来一个Java语法中有趣的知识点,Q群175158287,欢迎同大家多多交流哈!今天给大家带来的是Java中list类的使用,java.util 包提供了l…

清华大学孙富春教授:基于知识智能的机器人技能学习

来源:学术通在刚结束的2019中国人工智能产业年会分论坛——“知识智能及其产业应用论坛”上,清华大学计算机科学与技术系教授、中国人工智能学会副理事长、国家杰青孙富春教授发表了题为《基于知识智能的机器人技能学习》的报告。孙富春教授报告聚焦人工…