一些汇编练习,代码可能有有些bug,不是太完美,更多请见
https://lartpang.github.io/myasm/
仓库调整了下,放到了组织下,https://github.com/DUT-Lab/AsmExamples
习题4:
- 从屏幕上输入大写字母,转换为小写字母并输出(生成.com文件)
要求:程序具有可读性、容错性
思路:
由于要生成.com文件,所以需要将文件代码设置到一个代码段里。本问题涉及到读入与显示,这里可以使用21h中断的1,2,9号子功能。
读入字符后,将al中存放的字符通过判断其是否为大写字母来保证程序的正确性。利用大小写ascii码上的对应关系,实现了大小写的转化。
代码如下:
- 编写一子程序 asc2bin ,将 ASCII 转换为二进制数
要求:
输入参数:AL 中存放需要转换的 ASCII
输出参数:AL 中存放转换后的二进制数并返回
思路:
对于ascii码,先都当做数字来处理,即都减30h,在与9比大小,大于9的说明是10~15,再减7即可。
代码如下:
- 内存中存放8个16位有符号数,求8个数值之和,并将结果存放在内存变量SUM中
注:程序中应用到字扩展为双字的指令CWD
思路:
通过使用循环加法,扩展双字的指令,转化为双字的计算加和。
代码如下:
- 内存中存放 8 个 8 位有符号数,请按从大到小顺序排列
思路:
利用冒泡排序,设置两个循环,将相邻的数字进行比较,大的放在低位地址,小的放在高位地址。
对于循环的次数的设置这里有些需要注意的地方。一般而言,n个数的问题,外层循环需要n-1次,而内层循环也是需要n-1次比较,所以可以设置使用相同的循环计数器。只需要内层循环计数的时候将之前的压栈保存即可。
代码如下:
- 内存中有8个16位数,请编写程序将8个数倒序排放
例:定义内存中8个数 buf dw 100, 3, 1, 20, 40, -2, 7, 10
程序运行后,buf 开始应为: buf dw 10, 7, -2, 40, 20, 1, 3, 100
思路:
要实现倒序存放,利用栈的入栈出栈,或者反复循环交换。但是使用栈,更为便捷。
代码如下:
- 从键盘输入 4 位十进制数,然后以 16 进制形式显示在屏幕上
例:键盘输入:1024 屏幕上应显示:0400H
要求:键盘输入和显示结果时均应有提示
思路:
输入四位十进制数,将ascii码利用中断功能,读入(此处会对输入字符做出合法性判断),转换为十进制数并以二进制的形式存在内存里,最后,转换为十六进制,并拆分各个数字,显示ascii码输出。具体流程详见注释。
代码如下:
- 数据段从100H开始存放字符串str1,从200H开始存放str2,二者均以NULL字符为结束符,编写程序将str2拷贝到str1末尾,形成一个完整字符串
例:
ORG 100H
str1 db 0dh, 0ah, ‘Hello ’, 0
ORG 200H
str2 db ‘Automation!’, 0
程序运行后结果应为:
str1 db 0dh, 0ah, ‘Hello Automation!’, 0
思路:
利用repnz scasb
指令,将扫描的字符与al中预存的0比较,即查找str_first的结束位置,找到后,利用mov cx, count
& rep movsb
两条命令,以及count equ ($-str_second)
,将str_secon复制到str_first之后。
最后再利用lodsb,配合中断功能,显示最终的合并字符串。
代码如下:
- 以 10 进制形式显示 内存中一有符号字节数据
例:var db 0ffH
屏幕应显示:The result is: -1
代码如下:
思路:
主要是二进制转化为十进制后拆分成单个数字,在将之处理为ascii码。
首先需要与0比较,利用jg/jl等有符号数比较指令实现跳转处理。分别将第一个字符设置为对应的符号。
再将实际数值部分进行处理,转换为ascii码,进行显示。
代码如下:
- 将一个16位的无符号数var,转换为非压缩格式BCD码,存放在内存中buf开始的单元中。(按高位在 前、低位在后的顺序存放)
思路:
利用二进制转换十进制:((0*2 + B15)*2 + B14)*2 + ? + )*2 + B0
在运算过程中利用非压缩格式bcd码调整指令aaa,处理为非压缩格式bcd码,使得最终结果即为非压缩格式bcd码。
代码如下:
- 内存中有两个32位有符号数,请编写完整汇编语言程序,将二者相乘,结果保存在64位有符号数RESULT中
思路:
两个32位与符号数相乘,只要处理好符号位,就可以转化为无符号数相乘。
代码如下:
- 将一个 8 位压缩 BCD 码转换为二进制数
思路:
对于四位压缩bcd码的过程比较简单,可以利用不断循环左移四位,将高位字节的两个bcd码置于字单元的最后位置,整体赋给寄存器,现在寄存器里存放的是一位压缩bcd码,乘以10再加上下一位如此获得的bcd码,反复如此,就可以获得四位的压缩bcd对应的十进制,存放到内存中,就变为了二进制。
而对于八位压缩bcd码,则可以拆成高四位对应的十进制,乘以10000,加上低四位对应的十进制数。这里就是这样处理的。
高四位低四位分别求出了对应的十进制,按上述规则相加,得到了最终结果。
代码如下:
选作题:
- 内存中从str开始存放一字符串,结束符为NULL字符,请编写程序统计该字符串中单词的个数
例:str1 db 0dh, 0ah, ‘Hello world, welcome to DUT. CPU is central
processing unit!’, 0h
统计 ’….’ 中的单词个数,结果为10
思路:
如题所述,主要统计空格。通过扫描字符串,统计空格,但是有效的空格前一个字符是有效的字符,只有这样的空格才会统计。
代码如下: