汇编第二次试验
来源:互联网 发布:mysql group by 索引 编辑:程序博客网 时间:2024/05/18 01:30
这次实验有三个题目,用了一整天时间,收获颇丰,最重要的是思想上的冲击!让我真的感觉到汇编语言和高级语言的想法就是不一样!
心路历程:其实写汇编真的思维和写其他高级语言完全不同,因为汇编它是要么顺序执行A,要么跳转到B执行,但是有可能顺序执行后A根据题意是不能执行B的,于是就出现矛盾了,或者根本就跳转不回来!!如下例子:
其实感觉写汇编的跳转指令有点像提取公因式!把无论是顺序执行还是跳转执行的相同部分放在最后,让他们能够顺序执行完,否则将会出现矛盾!
DATAS SEGMENT
array dw 3 DUP(0)
flag db 0;这个最大的缺点就是会重复计算因为A1=A2=A3判断3次其实应该是
DATAS ENDS ;输出2,但实际它输出的却是3
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
mov flag,0;设置一个标志位
mov si,0 ;设置初始偏移地址
mov cx,3
Input:
mov ah,01h;循环输入数字
int 21h
mov ah,0h
mov ds:array[si],ax;把输入的数字赋值给存储器
inc si
loop Input
mov si,0;重置si为0
mov cx,2;重置cx为2
Compare:
mov ax,ds:array[si]
mov bx,ds:array[si+1]
cmp ax,bx
jz count 这里本来想计数,但是跳入
inc si
loop Compare
mov ax,ds:array[0]
mov bx,ds:array[2]
cmp ax,bx
jz count
count:这里后!!就回不来了!,如果再写一个jmp Compare,那么程序每次顺序执行到这里时就不停跳转,进入死循环!!!但是高级语言直接if(){count++;}就可以了!
add flag,1
sub flag,1
mov dl,0ah
mov ah,02h
int 21h
mov dl,0dh
mov ah,02h
int 21h
add flag,30h
mov dl,flag
mov ah,02h
int 21h
MOV AH,4CH
INT 21H
CODES ENDS
END START
1.试编写一汇编语言程序,要求从键盘接收一个4位的16进制数,并在终端上显示与它等值的二进制数。
DATAS SEGMENT
; head db "please enter 4 integers: $";
;此处输入数据段代码
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
mov ch,4 ;用于输入循环使用
mov cl,4 ;用于 bx移位使用
sub bx,bx ;初始化 bx
sub ax,ax ;初始化 ax
sub dx,dx ;初始化 dx
input:
mov ah,1h ;输入一个 16进制数字
int 21h
sub al,30h ;存进去是 ASCII,先判断是不是数字
jl exit ;如果该数字小于 0就跳出
cmp al,9d ;判断是不是 0-9,把它变为 16进制的 0-9
jle printit ;是 0-9,就跳转到 printit
sub al,7h ;不是 0-9,把它变成 16进制的 A-F
printit:
;and al,0fh;把al 的高四位清零,注意注意!!可能覆盖!!
;mov bl,al;把al 的数据传给bl
shl bx,cl ;将 bx左移 4位,第一个输入的数据存在了 bl的高四位
or bl,al
dec ch ;将 ch-1
jnz input;如果 ch不为 0,就继续输入一个数字
sub cx,cx
mov cx,16
mov dl,0dh
mov ah,2
int 21h
mov dl,0ah
mov ah,2
int 21h
output:
mov dl, '0'
shl bx,1 ;将 bx左移一位,最高位存在 CF里
jnc action;如果 CF=0就跳到action0
mov dl, '1'
;jc action1;如果CF=1 就跳到action1
action:
mov ah,02
int 21h
loop output
exit:
ret
MOV AH,4CH
INT 21H
CODES ENDS
END START
(1)要注意的是:当用户输入一个一个数字或者字母,它存放在系统里面是一个ASCII值,比如输入9d,它存的其实是39h,所以要先判断,所以要sub al,30h ;存进去是 ASCII,先判断是不是数字
不是就在判断是不是字母,如果是0-9就直接跳入printit,注意无论是字母还是数字都要执行printit,所以可以它直接安排在后面!!
(2)要把数据全部存入bx中,要移位!注意!
shl bx,cl
要把如果是数字则只能是1!即 shl bx,1,否则必须要用cl先把数字存起来!!
(3)用or把al和bl对接!其实BX向左移动四位,那么bl都是有空间的,所以不用or ax,bx,用dec ch,让ch自减去1再循环!
(4)虽然数字都存进去了,但是输出的时候汇编会把它自动识别为ASCII码!!!例如下图:
所以还是用shl一位一位的把数字存到CF里,再通过jnc识别!最后输出!!注意这里的dl里的数字不同,所以不能都写在action里!!
2.
用15行*16列的表格形式显示ASCII码为10H-FFH的所有字符(双重循环程序)
DATAS SEGMENT
;此处输入数据段代码
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
mov dx,0010h ;先将 dx的赋初值为 0010h
first:
mov cx,10h ;将计数寄存器的初值定为 16次,因为有 16列
second:
mov ah,02h
int 21h
inc dx
push dx ;第一次的话就是保存 dx中 0011h内容
mov dl,0
mov ah,02
int 21h
pop dx
loop second
push dx
mov dl,0dh ;显示回车
mov ah,02h
int 21h
mov dl,0ah ;显示换行
mov ah,02h
int 21h
pop dx
cmp dx,100h ;;由于这里是小于才跳转,如果采用 cmp dx.0ffh
jb first;那么还没有显示 0ffh,程序就执行完了,所以要跟 100h比较
MOV AH,4CH
INT 21H
CODES ENDS
END START
这个实验最大的亮点就是用了PUSH和POP来保存dx的内容,这样就不用把数据暂存于其他的寄存器中了!!而且比较的是100h而不是0ffh因为最后一个会无法显示!
3.
编写一程序,要求比较数组Array中的三个16位补码数,并根据比较结果在终端上显示如下信息:
1、如果三个数都不相等则显示0;
2、如果三个数有两个数相等则显示1;
3、如果三个数都相等则显示2。
DATAS SEGMENT
array dw 3,3,3
;array dw 3,4,5
;array dw 3,4,3;此处输入数据段代码
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
compare12:
mov ax,ds:array[0] ;先比较第一个和第二个数 ,OPRT1和OPRT2 可以是寄存器或存储器
cmp ax,ds:array[2] ;但不能同时为存储器, OPRT2还可以为立即数。
jnz compare23 ;所以要把其中一个赋值给 ax
;如果不相等则跳转到 compare23,比较第一个数和第三个数
compare32: ;相等就顺序执行 compare32,因为相等判断的次数少一些
mov ax,ds:array[2] ;最后直接跳到 output就可以出去
cmp ax,ds:array[4]
mov dl,32h ;A1=A2=A3先把2 存入dl这样跳转到 output可以直接使用输出2
jz output ;相等就输出 2
mov dl,31h ;A1=A2!=A3不相等就把1 移入dl
jmp output ;无条件跳入 output输入
compare23: ;第一个数与第二个数不相等跳入!
mov ax,ds:array[2]
cmp ax,ds:array[4]
jnz compare13 ;不相等跳入 compare13
mov dl,31h ;A1!=A2=A3否则将1 移入dl
jmp output ;无条件跳转
compare13: ;比较第一个数与第三个数
mov ax,ds:array[0]
cmp ax,ds:array[4]
mov dl,30h ;A1!=A2!=A3
jnz output
mov dl,31h ;A1!=A2,A2!=A3 ,A1=A3
output: ;要把 output放在最后,因为前面所有的程序都要执行到它!!
mov ah,02h
int 21h
MOV AH,4CH
INT 21H
CODES ENDS
END START
注意!!!短的判断内容先写,直接跳出,因为写在后面长的判断很可能会经过短的判断!!
- 汇编第二次试验
- 第二次试验
- 第二次试验
- 第二次试验
- 第二次试验
- C++第二次试验
- c++第二次试验-01
- c++第二次试验
- c++第二次试验1
- C++第二次试验作业
- c++第二次试验2
- c++第二次试验
- c++第二次试验
- c++第二次试验
- 补c++第二次试验
- 编译原理第二次试验
- 高操第二次试验 进程
- 第二次试验2,3,4
- 【编程知识】面向对象基础知识总结
- C语言习题——编写一个程序,生产一个乘法表
- 排序算法(七)海量数据的排序问题
- 阿里云的CentOS环境中安装配置MySQL的教程
- 信息论与编码题库
- 汇编第二次试验
- vi / vim 编辑器的基本使用介绍
- PHP + mysql 对日期的操作
- PHP - 数组的排序函数
- 实现购物车商品数量+1、-1按钮的效果
- hdu4727 The Number Off of FFF
- 停车场
- shell有流程控制语句
- 原型设计的快速方法docker-compose