用汇编语言计算n!

用汇编语言计算n!,第1张

DATA SEGMENT 数据段定义

string db"Please input a number(0-10000):" ,0dh,0ah

wrongstring db"薯圆槐并 INPUT ERROR!INPUT ONCE MORE! ",0ah,0dh,'$'

inputbuffer db6,?,6 dup(?)

c10 dw10 输入时进制转换的数数明塌

n dw? 要求阶乘的数

m dw? 步长

c dw? 进位

i dw?

outputbuffer dw 30000 dup(?)

DATA ENDS

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

STACK SEGMENT PARA STACK 'STACK'堆栈段代码

DW 100 DUP(?)

STACK ENDS

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

CODE SEGMENT 码段定义

ASSUMECS:CODE,DS:DATA,SS:STACK

START:

MOV AX,DATA

MOV DS,AX

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

main proc

call input

call fractor

mov cx,di

routput:循环输出

push cx

mov di,cx

call output

pop cx

dec cx

cmp cx,0

jge routput

displaylength:

mov dl,0dh

mov ah,2

int 21h

mov dl,0ah

mov ah,2

int 21h

jmp Start

exit:

mov ah,07h

int 21h

mov ax,4c00h结束处理

INT 21H 返回DOS

main endp 结束过程

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

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

input proc near

lea bx,string

mov cx, 33

disstring:

mov dl,[bx]

mov ah,2

int 21h

inc bx

loop disstring

jmp inputinit

wronginput: 错误输入

lea dx,wrongstring

mov ah,9

int 21h

inputinit:初始化

lea dx,inputbuffer 装载输入缓冲区首地址

mov ah,0ah 输入功能代码

int 21h 从键盘输入一个数,以回车键结束

mov ax,0累加器清0

mov cl,inputbuffer+1循环次数

mov ch,0

lea bx,inputbuffer+2装载字符存放区首地址

inputone:

mul c10

mov dl,[bx]

cmp dl,'0'

jbwronginput

cmp dl,'9'

jawronginput

and dl,0fh

add al,dl

adc ah,0

inc bx

loop inputone

mov n,ax

mov dl,0dh

mov ah,2

int 21h

mov dl,0ah

mov ah,2

int 21h

ret

input endp

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

fractor proc near

mov cx,n

mov i,1d

mov m,0d

push dx

mov di,0d

mov ax,di

mov bx,2d

mul bx

mov si,ax

pop dx

mov outputbuffer[si],1d

ctrli:

mov c,0

mov di,0d

ctrldi:

cmp di,m

jbe done

jmp cmpc

done:

push dx

mov ax,di

mov bx,2d

mul bx

mov si,ax

pop dx

mov ax,outputbuffer[si]

mov bx,i

mul bx

add ax,c

adc dx,0

mov bx,10000

div bx

mov c,ax

push dx

mov ax,di

mov bx,2d

mul bx

mov si,ax

pop dx

mov outputbuffer[si],dx

inc di

jmp ctrldi

cmpc:

cmp c,0

jathree1

jmp next

three1:

inc m

mov ax,c

mov outputbuffer[si+2],ax

next:

inc i

cmp cx,0

jng if0

loop ctrli

if0:

mov di,m

ret

fractor endp

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

output proc near

C2:

push dx

mov ax,di

mov bx,2d

mul bx

mov si,ax

pop dx

mov bx,outputbuffer[si]

bid proc

mov cx,10000

mov ax,bx

mov dx,0

div cx

mov bx,dx

mov cx,1000

call ddiv

mov cx,100

call ddiv

mov cx,10

call ddiv

mov cx,1

call ddiv

ret

bid endp

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

ddiv proc

mov ax,bx

mov dx,0

div cx

mov bx,dx

mov dl,al

add dl,30h

mov ah,02h

int 21h

ret

ddiv endp

ret

output endp

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

CODE ENDS 结束段

END START 结束程序

.MODEL SMALL

Code Segment

Assume CS:Code,DS:code

CR equ 000DH

LF equ 000AH

KBBack equ 0008H

------------举尘颂-------------------------

功能:显示指定地址(Str_Addr)的字符串

入口:

Str_Addr=字符串地址(要求在数据段)

用法: Output Str_Addr

用法举例:Output PromptStr

Output MACRO Str_Addr

lea dx,Str_Addr

mov ah,9

int 21h

EndM

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

功能:输出一个字符

入口:dl=要显示的字符

Output_Chr proc Near

push ax

mov ah,02h

int 21h

pop ax

ret

Output_Chr endp

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

功能:输出回车换行

Output_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

Output_CTLF endp

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

功能:取光标位置

入口:无

出口:DH=行号,DL=列号

GetCursor Proc Near

PUSH AX

PUSH BX

PUSH CX

XOR BX,BX

MOV AH,3

INT 10H

MOV Cursor_Row,DH

MOV Cursor_Col,DL

POP CX

POP BX

POP AX

RET

Cursor_Row DB ?

Cursor_Col DB ?

GetCursor EndP

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

功能:置光标位置

入口:Cursor_Row=行坐标Cursor_Col: 列坐标)

SetCursor Proc Near

PUSH CX

PUSH BX

PUSH AX

MOV DH,Cursor_Row

MOV DL,Cursor_Col

XOR BX,BX

MOV AH,2

INT 10H

POP AX

POP BX

POP CX

RET

SetCursor EndP

-------------兄明------------------------

功能:键盘输入一个指定位数的十进制数字,将其转换成二进制数并保存在指定正郑的内存单元。

由于限定最大数据类型为字,所以,数字位数最多:5,最大无符号数:65536

约定:直接回车,视为数字0

入口:@@Digits=数字位数;di=保存输入的数字首地址

@@Type_Data=保存的数据类型,B=字节类型,W=字类型。

出口:转换后的二进制数保存在di所指的单元

Input_Digit Proc Near

push dx

push cx

push bx

push di

lea di,@@Save_Tmp

push di

cld

mov cl,@@Digits

xor ch,ch

push cx

@@Input: call GetCursor 取光标位置

mov ah,1 从键盘接受一个字符

int 21h

cmp al,CR 若键入的是回车,已经键入的数字不足N位

jz @@ASC_Dec 转去处理已经键入的数字

cmp al,KBBack

jz @@KB_Back 若是回空键,重新输入

cmp al,'0'

jb @@KBBack 若低于数字'0',重新输入

cmp al,'9'

ja @@KBBack 若低于数字'9',重新输入

jmp @@Save_Dig

@@KB_Back: dec Cursor_Col

inc cx

dec di

@@KBBack: call SetCursor 置光标位置

jmp @@Input

@@Save_Dig: and al,0fh 转换成二进制数

stosb 保存

loop @@Input 接受下一个数字

@@ASC_Dec: mov ax,cx

pop cx

pop si

sub cx,ax 实际输入的数字位数

xor bp,bp

xor dx,dx

xor ax,ax

jcxz @@Save_Ret 若直接回车,没有输入任何数字,按输入'0'处理

dec cx 实际输入的数字位数减1,准备把输入的这一串数字转换成二进制数

jcxz @@One_Digit 若输入的数字只有一位,转去直接保存这个二进制数

mov bx,10

@@Mul_Ten: lodsb

cbw

add ax,bp

mul bx

mov bp,ax

loop @@Mul_Ten

@@One_Digit: lodsb

cbw

add ax,bp

@@Save_Ret: pop di

cmp @@Type_Data,'B' 字节类型?

jz $+5

stosw

jmp $+3

stosb

pop bx

pop cx

pop dx

ret

@@Digits db ? 十进制数字位数

@@Type_Data db 'B' 保存的数据类型。B=字节类型,W=字类型

@@Save_Tmp db 16 dup(?)

Input_Digit EndP

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

功能:把AX中的二进制无符号数转换成显式的十进制ASCII码,并送显示屏显示

入口:AX=二进制数

出口:在当前光标位置显示转换后的ASCII码数字

Dec_ASCII Proc Near

push dx

push bx

push di

mov bx,10

lea di,@@Temp_Save[6]

mov byte ptr [di],'$'

dec di

cld

@@Divide: xor dx,dx

div bx

or dl,30h

mov [di],dl

dec di

test ax,0ffffh

jnz @@Divide

inc di

push di

pop dx

mov ah,9

int 21h

pop di

pop bx

pop dx

ret

@@Temp_Save db 7 dup(?)

Dec_ASCII EndP

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

加法运算

Addition Proc Near

mov ax,Number1

call Dec_ASCII 把AX中的二进制无符号数转换成显式的十进制ASCII码,并送显示屏显示

mov dl,'+'

call Output_Chr 显示一个加号

mov ax,Number2

call Dec_ASCII 显示第二个数

mov dl,'='

call Output_Chr 显示一个等号

mov ax,Number1

add ax,Number2 Number1+Number2→AX

call Dec_ASCII 显示和

ret

Addition EndP

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

减法运算

Subtration Proc Near

mov ax,Number1

call Dec_ASCII

mov dl,'-'

call Output_Chr 显示一个减号

mov ax,Number2

call Dec_ASCII 显示第二个数

mov dl,'='

call Output_Chr 显示一个等号

mov ax,Number1

sub ax,Number2 Number1-Number2→AX

call Dec_ASCII 显示差

ret

Subtration EndP

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

乘法运算(请事先算好了,否则,容易导致乘积超过16位寄存器能够表示的范围)

Multiple Proc Near

mov ax,Number1

call Dec_ASCII

mov dl,'*'

call Output_Chr 显示一个乘号

mov ax,Number2

call Dec_ASCII 显示第二个数

mov dl,'='

call Output_Chr 显示一个等号

mov ax,Number1

mul Number2 Number1*Number2→AX

call Dec_ASCII 显示乘积(假定乘积不超过16位寄存器能够表示的范围)

ret

Multiple EndP

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

除法运算

Division Proc Near

mov ax,Number1

call Dec_ASCII

mov dl,'/'

call Output_Chr 显示一个除号

mov ax,Number2

call Dec_ASCII 显示第二个数

mov dl,'='

call Output_Chr 显示一个等号

xor dx,dx

mov ax,Number1

div Number2 Number1/Number2→AX(商),DX(余数

call Dec_ASCII 显示商数的整数部分

test dx,0ffffh 判断余数是否为0

jnz $+3 不能整除,计算余数

ret

push dx

mov cx,6

mov dl,'.'

Disp_Dot: call Output_Chr 显示一个等号

loop Disp_Dot

pop ax 余数

call Dec_ASCII 显示余数部分

ret

Division EndP

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

Number1 dw ?

Number2 dw ?

prompt_One db 'Please the first number: $'

prompt_Two db 'Please the second number: $'

Press_Key db13,10,13,10,'The complated. Press any key to exit...$'

Start:push cs

pop ds

push cs

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

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

输入两个十进制数

Output prompt_One 提示输入第一个数

mov @@Digits,4 十进制数字位数

mov @@Type_Data,'W' 保存的数据类型。B=字节类型,W=字类型

lea di,Number1 变量Number1的地址

call Input_Digit 从键盘接受一个N位数字

call Output_CTLF 输出一个回车、换行

Output prompt_Two 提示输入第一个数

lea di,Number2 变量Number1的地址

call Input_Digit 从键盘接受一个N位数字

call Output_CTLF 输出一个回车、换行

call Output_CTLF 输出一个回车、换行

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

call Addition 加法运算

call Output_CTLF 显示一个回车、换行

call Subtration 减法运算

call Output_CTLF 显示一个回车、换行

call Multiple 乘法运算

call Output_CTLF 显示一个回车、换行

call Division 除法运算

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

Exit_Proc: Output Press_Key 提示 *** 作完成,按任意键结束程序

mov ah,1

int 21h

mov ah,4ch 结束程序

int 21h

Code Ends

END Start 编译到此结束


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

原文地址: http://outofmemory.cn/yw/12358322.html

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

发表评论

登录后才能评论

评论列表(0条)

保存