求 十六位十进制求和 8086汇编 代码

求 十六位十进制求和 8086汇编 代码,第1张

MODEL SMALL

DATA

X1 DB '1234567890123456' ; 16位的十进制被加数

X2 DB '9233445566778899' ; 16位的十进制加数

Y1 DB '00000000000000000' ; 17位的十进制加法的和(考虑最高位可能有进位产生)

CODE

STARTUP

LEA SI, X1

LEA DI, X2

LEA BX, Y1

ADD SI, 15 ; SI 指向被加数的最右端的个位数

ADD DI, 15 ; DI 指向加数的个位数

ADD BX, 16 ; BX 指向加法的和的个位数

MOV CX, 16 ; 循环16次

CLC ; 运算前将CF清0

PUSHF ;PSW标志寄存器入栈保存

AGAIN:

POPF ; PSW标志寄存器出栈,恢复CF

MOV AL, [SI] ;取被加数到AL

ADC AL, [DI] ;将加数加到AL中

AAA ;非压缩的BCD码(即ASCII码)加法调整

MOV [BX], AL ; 保存加得的和

PUSHF ; PSW标志寄存器入栈,主要是为了保存好CF标志

AND BYTE PTR [BX], 0FH ;将这一位加法的和的高4位清零

ADD BYTE PTR [BX], 30H ; 将这一位加法的和调整成数字的ASCII码

DEC SI ; 调整指针,处理下一位

DEC DI

DEC BX

LOOP AGAIN

POPF ; 这一小段指令处理最后的进位形成的第17位

MOV AL, 0

ADC AL, 0

ADD AL, 30H

MOV [BX], AL

EXIT

END

程序说明:

1 很长的整数,直接按每一位用一个字节的数字字符的ASCII码存储,16位的十进制数就是一个由16个数字字符构成的字符串

2 加法运算,是将每个ASCII字符看成是非压缩的BCD码,在AL中进行过加法运算后,用非压缩的BCD码调整指令将结果调整成非压缩的BCD码格式,加法的进位保存在CF中。运算规则完全按照手工计算的方法进行,依个位、十位、百位……的次序从右向左逐位相加,在相加时带上上一位的进位。程序共循环16次。

3 为了避免指针调整和循环控制时CF被这些运算结果所修改,造成运算结果错误,需要用堆栈保存PSW的方法保护CF,运算结果调整好以后立即保存CF,下次运算前恢复CF。

4 程序只考虑了运算,没有考虑显示。可以在调试程序中查看运算结果是否正确。若需要加上显示功能,对数据段的定义稍加修改,用09H号DOS系统功能调用即可。

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 db 56,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 db 6 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 ;编译到此结束

8086是16位的,你问的应该是把BH(或者BL)的低八位和高八位分别送至DL和DH之中吧,下面我就举例把BH的高八位送至DH,低八位送至DL,(假如你想把BL拆分的话,只要把BH换为BL就可以了)只写主要部分给您,其他的不写

MOV AH,BH

AND BH,0F0H

MOV DH,BH

AND AH,0FH

MOV DL,BH

假如你真的想要将寄存器BX的高8值传送到寄存器DH,低8位传送到 寄存器DL

直接送就可以了

MOV DH,BH

MOV DL,BL

或者直接MOV DX,BX

1、程序如下:

code segment

assume cs:code, ds:code, ss:code

org 100h

main: mov si,offset x ;取数组中第一个元素的内存地址

mov cx,100 ;数组元素个数

cld ;以下使用lodsb来获得各元素值,为此先清除方向标志

xor ah,ah ;因x内全部为无符号数,所以将ah设为0,以便累加(根据 _fmlyht 意见从循环内移出以提高代码效率)

lab1: lodsb ;从ds:si处取一个字节放入al中,同时si增1即指向下个元素

add sum,ax ;累加

loop lab1 ;循环,前面对cx的赋值规定了循环次数为100次

int 20h ;循环结束后sum中为总和,此处用int 20h退出

x db 100 dup () ;定义100个字节型元素的数组,但不指定初值

sum dw 0 ;sum的初值为0,在程序代码部分中没有对该变量进行初始化,所以会使用这里定义的值为总和的初值

code ends

end main

2、代码如下:

cmp ax,bx ;比较ax与bx

jge lab2 ;若ax>=bx则转至lab2,带符号数比较须使用jg(e)/jl(e)/jng/jnl等指令

xchg ax,bx ;根据 _fmlyht 意见,将ax与bx交换,如此,ax中为两者的较大值,bx为较小值

lab2: cmp ax,cx ;执行到此时,ax中有最初时ax与bx中较大者,这时再比较ax与cx

jge lab3 ;方法与前次类似,至lab3时ax将存有原来三者中最大的数

xchg ax,cx ;没有跳转的话需将cx中较大的值与ax中较小的值交换以使ax中含最大值

lab3:

;至此ax中已是三者中的最大值,下面代码是为完成中间值与最小值的排序,使三者从大到小分别存放于ax、bx、cx。原题无此要求,可去掉。

cmp bx,cx

jge lab4

xchg bx,cx

lab4:

;至此,ax>=bx>=cx

----

谢谢楼下 _fmlyht 朋友指正,已在此答案中改进并注明。

为了简便,直接使用了21中断的输入字符串子功能,即使你不输入#作为结束符,也可以使用。

统计时,则将'#'后面的字符忽略

正确的作法,是调用21中断的1号子功能,每次读取一个字符,直到读取到'#'为止。

这个修改很简单,我就不再写了。

data segment

  buf db 255 ;

        db 

            db 255 dup('$')

    c1 dw 0 ;spacebar

    c2 dw 0 ;digital number

    c3 dw 0 ;alphabet

    m1 db 0dh, 0ah, "Spacebar number:$"

    m2 db 0dh, 0ah, "Digital number:$"

    m3 db 0dh, 0ah, "Alphabet number:$"

data ends

code segment

        assume cs:code, ds:data

start:

        mov ax, data

        mov ds, ax

        mov es, ax

;code start here

; read string

        lea dx, buf

        mov ah,0ah

        int 21h

;

    xor cx, cx

        mov cl, buf+1

        mov si, 0

Loop1:

        mov al, buf[si+2]

        cmp al, '#'

        jz  lopend

        cmp al, 20h

        jz space

        cmp al, '0'

        jb alphabet

        cmp al, '9'

        ja alphabet

        inc c2      ;digital number

        jmp lop

space:

        inc c1      ;spacebar

        jmp lop

alphabet:

        inc c3

lop:

        inc si

        loop loop1

lopend:

; print result

        lea dx, m1

        mov ah, 9

        int 21h

        mov ax, c1

        call print

        lea dx, m2

        mov ah, 9

        int 21h

        mov ax, c2

        call print

        lea dx, m3

        mov ah,9

        int 21h

        mov ax, c3

        call print

;exit to OS

        mov ah,4ch

        int 21h

print proc near

        mov bx, 10

        xor cx, cx

Q0:

        xor dx, dx

        div bx

        or dx, 0e30h

        push dx

        inc cx

        cmp ax, 0

        jnz Q0

Q1:

        pop ax

        int 10h

        loop Q1

        ret

print endp

code ends

end start

以上就是关于求 十六位十进制求和 8086汇编 代码全部的内容,包括:求 十六位十进制求和 8086汇编 代码、8086的编程题(使用汇编语言)、编写8086汇编语言程序,将寄存器BX的高8值传送到寄存器DH,低8位传送到 寄存器DL。等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址: http://outofmemory.cn/zz/9624758.html

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

发表评论

登录后才能评论

评论列表(0条)

保存