8086的编程题(使用汇编语言)

8086的编程题(使用汇编语言),第1张

1、编两个通用过程完成将AX中存放的二进制数转换成压缩型BCD码以及将BCD码转换成二进制数。

本程序通过编译,运行正确。

Code Segment

Assume CS:Code,DS:Code

-----------------------------------------

功能:将AX中的二进制数转换成压缩型BCD码

入口:AX=16位二进制数(因为压缩BCD码最大为:9999H,所以,AX的二进制值不能大于270FH)

出口:AX=转换后的压缩型BCD码

Binary_BCD Proc Near

push dx

push cx

push bx

push di

mov @@Temp_Save,0

mov @@Temp_Save[2],0 将临时两个字存储单元置0

mov bx,10

lea di,@@Temp_Save[3]

cld

@@Divide: xor dx,dx

div bx

mov [di],dl 保存余数

dec di

test ax,0ffffh

jnz @@Divide

mov cl,4

mov ax,@@Temp_Save[2]

xchg ah,al

shl al,cl

shl ax,cl

mov dl,ah

mov ax,@@Temp_Save

xchg ah,al

shl al,cl

shl ax,cl

mov al,dl

pop di

pop bx

pop cx

pop dx

ret

@@Temp_Save dw 2 dup(?)

Binary_BCD EndP

-----------------------------------------

功能:将AX中的压缩型BCD码转换成二进制数

入口:AX=压缩型BCD码

出口:AX=转换后的16位二进制数

BCD_Binary Proc Near

push dx

push cx

push bx

mov dx,ax

mov bx,10

mov cl,4

shr ah,cl

xchg ah,al

cbw

push dx

mul bx

pop dx

and dh,0fh

xchg dh,dl

push dx

xor dh,dh

add ax,dx

mul bx

pop dx

xchg dh,dl

xor dh,dh

push dx

shr dx,cl

add ax,dx

mul bx

pop dx

and dl,0fh

add ax,dx

pop bx

pop cx

pop dx

ret

BCD_Binary EndP

-----------------------------------------

Start: push cs

pop ds

push cs

pop es 使数据段、附加段与代码段同段

mov ax,3456

call Binary_BCD 将AX中的二进制数转换成压缩型BCD码

call BCD_Binary 将AX中的压缩型BCD码转换成二进制数

Exit_Proc: mov ah,4ch 结束程序

int 21h

Code ENDS

END Start 编译到此结束

2、在附加段中有一个数组,首地址为BUFF,数组中第一个字节存放了数组的长度.编一个程序在数组中查找0,找到握做后把它从数组中尺简删去,后续项向前压缩,其余部分补0。

本程序通过编译,运行正确

Code Segment

Assume CS:Code,DS:Code

BUFF db 10,56,78,35,0,89,51,63,0,76,123

Start: push cs

pop ds

push cs

pop es 使数据段、附加段与代码段同段

cld

lea si,BUFF 数组首地址→si

lodsb 读数段困衡组长度

xor ah,ah

push ax

pop cx 数组长度→cx

Find_Zero: lodsb 数组元素读入累加器al

cmp al,0 是否为0

jnz Next_One 不是0,跳转,处理下一个元素

-----------------------------------------

找到0,把它从数组中删去,后续项向前压缩,其余部分补0。

push si

pop di

dec di

push di

push cx

dec cx

rep movsb

mov byte ptr [si-1],0

pop cx

pop si

-----------------------------------------

Next_One: loop Find_Zero

Exit_Proc: mov ah,4ch 结束程序

int 21h

Code ENDS

END Start 编译到此结束

3.编程序统计学生的数学成绩,分别归类90分~99分,80分~89分,70分~79分,60~69,及60分以下,并将各段的人数送入内存单元中。

本程序通过编译,运行正确

Code Segment

Assume CS:Code,DS:Code

-----------------------------------------

功能:输出回车换行

enter_CTLF proc Near

push ax

push dx

mov ah,02h

mov dl,0dh

int 21h

mov dl,0ah

int 21h

pop dx

pop ax

ret

enter_CTLF endp

-----------------------------------------

功能:把AL中的二进制无符号数转换成显式的十进制ASCII码

入口:AL=二进制数;di=转换后的ASCII保存地址

出口:无

Dec_ASCII Proc Near

push si

push cx

push bx

push di

mov bl,10

xor cx,cx

lea di,@@Temp_Save[3]

cld

@@Divide: xor ah,ah

div bl

or ah,30h

mov [di],ah

dec di

inc cx

test al,0ffh

jnz @@Divide

push di

pop si

inc si

pop di

pop bx

push di

rep movsb

mov byte ptr [di],'$'

pop di

pop cx

pop si

ret

@@Temp_Save db 4 dup(?)

Dec_ASCII EndP

-----------------------------------------

Score db56,69,84,82,73,88,99,63,100,80,0,10,80,100,90,73,43,60,63,72,88,42,58,99,100,89,65,61,74,84,79,2,60,61,62,62,66,82,79,71,62,63 成绩单

Elements equ ($-Score)/Type Score 元素个数

Score_Tab db6 dup(0) 各分数段计数

Resault db'00---59: '

Temp_STr db 4 dup ('$')

Score100 db'====100: '

Start: push cs

pop ds

push cs

pop es 使数据段、附加段与代码段同段

cld

lea si,Score 成绩首地址

mov cx,Elements 成绩数目

mov dl,10 用于除10

Read_Score: lodsb 提取成绩

div dl 除10

cmp al,5 >5,及格

jg$+4

mov al,5 <=5,不及格

sub al,5 减5,分数段计数地址偏移量

cbw

push ax

pop bx

inc Score_Tab[bx] 计数增1

loop Read_Score 循环,统计下一个成绩

显示统计结果

mov bl,59h

mov cx,5

lea si,Score_Tab 各分数段计数数组首地址

lea di,Temp_STr

lea dx,Resault 统计结果字符串地址

List_Resault:

lodsb 读入计数值

call Dec_ASCII

mov ah,9 显示统计结果

int 21h

call enter_CTLF

mov al,bl

add al,1

daa

mov bl,al

push cx

mov cl,4

xor ah,ah

shl ax,cl

shr al,cl

or ax,3030h

xchg ah,al

mov word ptr Resault,ax

mov al,bl

add al,9

mov bl,al

xor ah,ah

shl ax,cl

shr al,cl

or ax,3030h

xchg ah,al

mov word ptr Resault[5],ax

pop cx

loop List_Resault

push si

push di

lea si,Score100

lea di,Resault

lea cx,Temp_STr

sub cx,di

rep movsb

pop di

pop si

lodsb 读入计数值

call Dec_ASCII

mov ah,9 显示统计结果

int 21h

Exit_Proc: mov ah,4ch 结束程序

int 21h

Code ENDS

END Start 编译到此结束

题目没写明白:

没说清array里是所有人的成绩还是只这几个人的;

没说清是所有人都加5分还是只是低于80的加;

没说清总分是所有人的还是只这几个人的、是加分后的还是加分前的;

只好按我的理解来写:

array里可能是全班人的成绩(比如20个人)

只是给不够80分人的加5分、并且没亏型只显示出这些人加分后的成绩

总分是所有人调整后的分数和

另外注意程序是把所有低于80分的都处理(而不是数7个完事)

程序如下:

students equ 20

.model small

.stack 2048

.data

array db 100,99,88,77,66,90,80,70,60,40,20,91,95,96,79,76,55,99,100,88

new db students dup (?)

sum dw 0

crlf db 13,10,36

txt db 'SUMMARY OF CLASS: $'

.code

main: mov ax,seg array

mov ds,ax

mov es,ax

mov si,offset array 将使用lodsb从array中读入分数(由ds:si定位)

mov di,offset new 并按要求将新分数存至new中(由es:di定位)

mov cx,students 学生人数即循环次数

cld为lodsb/stosb指令清除方向标志

mov bx,1 为输出美观,用bx当学号吧

lp: mov dl,'(' 这段输出学号,学号两边用括号扩起来

call putc

push bx 学号

call print

mov dl,')'

call putc

mov dl,9 用制表符分开

call putc

lodsb从array数组读一个分数(字节型数据)

xor ah,ah ah清零,算总分时是要加上高8位的

cmp al,80 是否高于80分

jae above80 大于或等于80分的跳过

add al,5 低于80的加5分

mov dl,'*'枯猜 先输出一个星号表示该成绩是调整后的成绩

call putc

above80: stosb所有人的最终成绩存回new数组

add sum,ax 最终成绩加到总分里

push ax 输出该生最终成绩

call print

mov dx,offset crlf 回车空散换行

call puts

inc bx 假装学号加1

loop lp 循环

call puts 再换行一下

mov dx,offset txt 输出全班总分的标题

call puts

mov ax,sum

push ax

call print 输出总分

mov dx,offset crlf 回车换行

call puts

mov ah,4ch 程序结束

int 21h

print proc near

mov bp,sp

push ax

push bx

push cx

push dx

mov ax,[bp+2]

call printax

pop dx

pop cx

pop bx

pop ax

ret 2

print endp

以10进制输出ax中的无符号整数

printax proc

mov bx,10 bx是除数

or ax,ax 是0则直接输出

jnz @f

mov dl,'0'

callputc

ret

@@: xor dx,dx

div bx

mov cx,ax

or cx,dx 若商与余数都为0则结束递归

jz @f

pushdx 留存DX中的余数以在递归后输出

call@b 递归

pop dx 从最高位开始恢复余数

add dl,'0'

callputc

@@: ret

printax endp

putc proc

push ax

mov ah,2

int 21h

pop ax

ret

putc endp

puts proc

pushax

mov ah,9

int 21h

pop ax

ret

puts endp

end main

执行结果:

(1) 100

(2) 99

(3) 88

(4) *82

(5) *71

(6) 90

(7) 80

(8) *75

(9) *65

(10)*45

(11)*25

(12)91

(13)95

(14)96

(15)*84

(16)*81

(17)*60

(18)99

(19)100

(20)88

SUMMARY OF CLASS: 1614

.model small 小模式编译

.386 386保护模式

DATA SEGMENT 数据段定义,下面的内容你看就明白

buf db 100, 0 ,100 DUP (0)

msg1 db 'Please input a string: ',0DH,0Ah,'$'

crlf db 0Dh,0Ah,'$'

leng db 0

DATA ENDS

STACK SEGMENT 堆栈段定义

DB 64 DUP (?)

STACK ENDS

CODE SEGMENT 执行代码段,即程序代码

assume cs:CODE,ds:DATA,es:DATA,ss:STACK

START: 执行开始

mov ax,DATA 数据段地址赋值给ax

mov ds,ax ds,es都指向数据段樱氏拆开始位置

mov es,ax

lea dx,msg1 输出提示文字

mov ah,09h

int 21h

lea dx,buf

mov ah,0ah 接受字符串

int 21h

mov dx,offset crlf

mov ah,09h 输出字符串中断,换行区别输入和输出的内容,防止混淆

int 21h

call count 计算输入的字符脊枣窜长度

call nospace把这行去掉之后是可以实现反向输出的,当然不能 去空格

lea dx,buf 下面的语句实现反向输出字符窜。

mov bl,leng新字符串长度送到bl

mov bh,00h

cmp bx,0000h

jnz L1

jz EXIT

L1:

mov dl,buf+1[bx] 把最后一位送到dl

mov ah,02h 输出一个字符中断

int 21h

dec bx 倒着输出字符

jnz l1

EXIT:

mov AH,4CH

int 21H

count:

xor dx,dx

xor cx,cx

lea di,buf

push di

mov al,0

lop:

cmp al,[di]

je done

inc dl

inc di

loop lop

done:

mov leng,dl把数组长度存至leng

pop di

ret

nospace: 去除输入字符窜中的空字符,并保存其长度。

push si

push di

push ax

push bx

push cx

lea si,buf

add si,2 读数据开始位置的值即指针到si,di

mov di,si 写指针di

xor ch,ch

mov cl,[si-1] 取定义的字符数组长度

cld 设置方向位

xor bl,bl 用来保存新的字符长度

L2:

lodsb 读取字符

cmp al,' '

je L3 如果是空格,跳过保存 *** 作

stosb 保存字符

inc bl 记录核哗长度

L3:

loop L2

mov leng,bl

pop cx

pop bx

pop ax

pop di

pop si

ret

CODE ENDS

END START

此程序的目的是把输入的字符窜去掉其中空格后实现反向输出。 不知是否符合你编程的目的。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/12400796.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-25
下一篇 2023-05-25

发表评论

登录后才能评论

评论列表(0条)

保存