用直接定址表这种方法有如下三个好处:
- 为了算法的清晰和间接
- 为了加快运算速度
- 为了使程序易于扩充
这个编程题,就是为了说明第二点,加快了运算速度。
下面编写一个程序,计算sinx的值,
程序运行如下:
代码
assume cs:code,ss:stack,ds:data
data segment
ARRAY db 87h,99h,0ah,0cdh,0DCH
data ends
stack segment stack
db 128 dup(0)
stack ends
code segment
start:
mov ax,stack
mov ss,ax
mov sp,128 ;初始化栈
call init_reg ;初始化源位置和目的位置
call show_sin
mov ax,4c00h
int 21h
;========================================================================
show_sin:
jmp showSin
degree0 db '0',0
degree30 db '0.5',0
degree60 db '0.866',0
degree90 db '1',0
degree120 db '0.866',0
degree150 db '0.5',0
degree180 db '0',0
ADDRESS_DEGREE dw OFFSET degree0 ;ADDRESS_DEGREE[0]0; 16可存4个16进制
dw OFFSET degree30 ;ADDRESS_DEGREE[2]1
dw OFFSET degree60 ;ADDRESS_DEGREE[4]2
dw OFFSET degree90 ;...
dw OFFSET degree120
dw OFFSET degree150
dw OFFSET degree180 ;ADDRESS_DEGREE[12]6
;;;;;;;=================================================================
showSin:
push ax
push bx
push dx
push si
push di
mov dx,0
mov ax,90 ;这里应该写成自动从键盘输出
mov bx,30
div bx ;ax = ax/bx 商,也是在ADDRESS_DEGREE 中的第i个位置
mov bx,ax ; bx = ax
add bx,bx ;第i个位置*2=ADDRESS_DEGREE中的索引值
;下面取出ADDRESS_DEGREE[bx]的值,也是地址
mov si,cs:ADDRESS_DEGREE[bx]
mov di,160*10+40*2
call show_string
pop di
pop si
pop dx
pop bx
pop ax
ret
;===============================================================
;循环将cs:[si]的值按字节放入es:[di]中
show_string:
push dx
push ds
push es
push si
push di
showString:
mov dl,cs:[si] ; 这个位置是cs:[si]还是ds:[si]????? 按字节从ARRAY中读取;
cmp dl,0
je showStringRet
mov es:[di],dl
add di,2
inc si
jmp showString
showStringRet:
pop di
pop si
pop es
pop ds
pop dx
ret
;=============================================================
;初始化工作
init_reg:
mov bx,0b800h ;es目的位置
mov es,bx
mov bx,cs ;ds源位置
mov ds,bx
ret
code ends
end start
整个程序逻辑是:
在代码段中定义要输出的sin值,再按照数组方式定义每个sin值的位置