📄 cos.asm
字号:
;**************************************************************************
;余弦函数表的设计
;要求:保存0度--90度(间隔1度),从键盘输入角度值后,在屏幕上输出其对应的函数值。
;**************************************************************************
data segment
buffer db 7,?,8 dup(?) ;存放输入的度数
table dw 0000,9998,9994,9986,9976,9962,9945,9925,9903,9877
dw 9848,9816,9781,9744,9703,9659,9613,9563,9511,9455
dw 9397,9336,9272,9205,9135,9063,8988,8910,8829,8746
dw 8660,8572,8480,8387,8290,8192,8090,7986,7880,7771
dw 7660,7547,7431,7314,7193,7071,6947,6820,6691,6561
dw 6428,6293,6157,6018,5878,5736,5592,5446,5299,5150
dw 5000,4848,4695,4540,4384,4226,4067,3907,3746,3584
dw 3420,3256,3090,2924,2756,2588,2419,2250,2079,1908
dw 1736,1564,1392,1219,1045,0872,0698,0523,0349,0175
dw 0000
mess0 db 13,10,"Error:Invalid number!",13,10,'$'
mess1 db 13,10,"Error:Over flow!",13,10,'$'
flag db 0
data ends
code segment
assume cs:code,ds:data
main proc far
mov ax,data
mov ds,ax
mov ah,0ah ;输入度数
mov dx,offset buffer
int 21h
mov bl,buffer+1 ;在缓冲区末尾加上分号作为结束标记
mov bh,0
mov buffer[bx+2],';'
mov si,offset buffer+2
;由于余弦函数为偶函数,因此负数可取其绝对值计算
cmp byte ptr [si],'-'
jne main_plus
inc si ;忽略掉负号
main_plus:
call decibin ;将缓冲区中的数转换为二进制
mov bx,ax
mov ah,2 ;输出回车换行
mov dl,0dh
int 21h
mov dl,0ah
int 21h
mov ax,bx
call search ;查出函数值
cmp ch,-1
jne plus
mov dl,'-' ;函数值为负数时输出负号
mov ah,2
int 21h
plus: mov dl,cl ;输出整数部分
add dl,30h
mov ah,2
int 21h
mov dl,'.' ;输出小数点
mov ah,2
int 21h
mov ax,bx ;输出小数部分
call binidec
mov ax,4c00h ;return to DOS
int 21h
main endp
;-------------------------------------------------------------------------
;search子程:
;input:ax存放度数
;output:bx:小数部分
; ch=-1:函数值为负数
; cl:函数值的整数部分
;-------------------------------------------------------------------------
search proc near
mov cl,0 ;初始化整数部分(默认为零)
mov ch,-1 ;默认为负数
cmp ax,360 ;0<=ax<=360则转移
jle between_0_and_360
cwd ;将ax转化到[0,360]之间
mov bx,360
idiv bx ;(dx,ax)/bx
mov ax,dx ;ax中为转化好的度数
between_0_and_360: ;确定整数部分
cmp ax,0
jnz not_zero
mov cl,1
mov ch,1
jmp find ;ax=0时直接去查找
not_zero:
sub ax,180
cmp ax,0
jg search_plus
neg ax ;负数时求补
search_plus:
cmp ax,90
jl find ;[0,90)之间,直接去查找
sub ax,180 ;[90,180]之间时,函数值为正
neg ax
mov ch,1
find: mov bx,ax ;确定小数部分
shl bx,1
mov dx,table[bx]
mov bx,dx
ret
search endp
;-----------------------------------------------------------
;function:将十进制数转换为二进制数
;input:Si指向表达式
;output:转换后的数放在AX中
;instruction:遇到非数字字符就认为该串数字结束
; 如数字过大导致溢出,则输出提示信息后程序结束(error1)
; 若无数字则也输出提示信息后程序结束(error0)
;-----------------------------------------------------------
decibin proc near
push bx
push cx
push dx
mov bx,0
newchar:mov al,byte ptr [si]
sub al,30h
jl exit
cmp al,9d
jg exit
mov flag,1
cbw
;digit is now in AX
;Multiply number in BX by 10 decimal
xchg ax,bx
mov cx,10d
imul cx
jno c1
jmp decibin_error1
c1: xchg ax,bx
;Add digit in AX to number in BX
add bx,ax
jno c2
jmp decibin_error1
c2: inc si
jmp newchar
exit: mov ax,bx ;将得数存入AX
dec si ;保证SI指向的是数字的最后一个
cmp flag,0
je decibin_error0
pop dx
pop cx
pop bx
ret
decibin_error0: ;出错处理
mov ah,9
mov dx,offset mess0
int 21h
mov ax,4c00h
int 21h
decibin_error1:
mov ah,9
mov dx,offset mess1
int 21h
mov ax,4c00h
int 21h
decibin endp
;--------------------------------------------------
;function:将ax中的数(无符号数)转换为10进制数输出。
;input:ax
;output:none
;--------------------------------------------------
value equ 4 ;保留4位有效位
binidec proc near
push ax ;现场保护
push bx
push cx
push dx
;MAIN PART OF THE PROGRAM GOES HERE:
mov cl,0 ;计数器置零
mov bx,10
next: mov dx,0
div bx
push dx
inc cl
cmp cl,value ;只循环四次,输出四位
jne next
print: pop ax
mov dl,al
add dl,30h
mov ah,2
int 21h
dec cl
jne print
pop dx ;现场恢复
pop cx
pop bx
pop ax
ret
binidec endp
code ends
end main
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -