1. 程序中,code、a、b、start、s 都是标号。这些标号仅仅表示了内存单元的地址
assume cs:code
; 把 a 中的各数相加放到 b 里
code segment
a: db 1,2,3,4,5,6,7,8 ;在后面加有 :的地址标号,只能在代码段中使用,不能在其他段中使用。
b: dw 0
; -d cs:0
; 0E24:0000 01 02 03 04 05 06 07 08-01 00 BE 00 00 BB 08 00 ................
start:mov si,offset a
mov bx,offset b
mov cx,8
s: mov al,cs:[si]
mov ah,0
add cs:[bx],ax
inc si
loop s
; AX=0008 BX=0008 CX=0000 DX=0000 SP=0000 BP=0000 SI=0008 DI=0000
; DS=0E14 ES=0E14 SS=0E23 CS=0E24 IP=001E NV UP EI PL NZ NA PO NC
; 0E24:001E B8004C MOV AX,4C00
; -d cs:0
; 0E24:0000 01 02 03 04 05 06 07 08-24 00 BE 00 00 BB 08 00 ........$.......
mov ax,4c00h
int 21h
code ends
end start
2. 描述了单位长度的标号
assume cs:code
code segment
; 标号a、b后面没有":",因此它们是可以同时描述内存地址和单元长度的标号。
a db 1,2,3,4,5,6,7,8
; 标号a,描述了地址code:0,和从这个地址开始,以后的内存单元都是字节单元
; 标号b描述了地址code:8,和从这个地址开始,以后的内存单元都是字单元。
b dw 0
start:mov si,0
mov cx,8
s: mov al,a[si]
mov ah,0
add b,ax
inc si
loop s
mov ax,4c00h
int 21h
code ends
end start
3. 使用数据标号来描述存储数据的单元的地址和长度
assume cs:code,ds:data ; 用伪指令assume将标号所在的段和一个段寄存器联系起来(编译器需要)
data segment
a db 1,2,3,4,5,6,7,8
b dw 0
data ends
code segment
start:mov ax,data
mov ds,ax ; 真正确定ds寄存器
; -d ds:0
; 0E24:0000 01 02 03 04 05 06 07 08-00 00 00 00 00 00 00 00
mov si,0
mov cx,8
s: mov al,a[si] ; 编译为:mov al,[si+0] 默认所访问单元的段地址在ds
mov ah,0
add b,ax ; 编译为:add [8],ax
inc si
loop s
mov ax,4c00h
int 21h
code ends
end start
data segment
a db 1,2,3,4,5,6,7,8
b dw 0
c dw a, b ;等价于c dw offset a, offset b
;数据标号c处存储的两个字型数据为标号a、b 的偏移地址
data ends
data segment
a db 1,2,3,4,5,6,7,8
b dw 0
c dd a,b ;等价于c dw offset a, seg a, offset b, seg b
;数据标号c处存储的两个双字型数据为标号a的偏移地址和段地址、标号b 的偏移地址和段地址
data ends
比如:
data segment
x db 1
a db 1,2,3,4,5,6,7,8 ; 偏移地址 0001
b dw 9999H ; 偏移地址 0009
m dw a,b ; 0001 0009
; -d ds:0
; 0E24:0000 01 01 02 03 04 05 06 07-08 99 99 01 00 09 00 00
data ends
4. 检测点 16.2
assume cs:code,es:data
data segment
a db 1,2,3,4,5,6,7,8
b dw 0
data ends
code segment
start:
mov ax,data
mov es,ax
mov si,0
mov cx,8
s: mov al,a[si]
mov ah,0
add b,ax
inc si
loop s
mov ax,4c00h
int 21h
code ends
end start
5. 以 16 进制形式在屏幕中间显示给定的字节型数据
; 以16进制形式在屏幕中间显示给定的字节型数据
assume cs:codesg
codesg segment
start: mov al, 0ABH
call showbyte
mov ax, 4c00h
int 21h
; ---------------------------------------------
showbyte:jmp short show
table db '0123456789ABCDEF' ; 字符表
show: push ax
push bx
push es
mov ah, al
shr ah, 1
shr ah, 1
shr ah, 1
shr ah, 1 ; 右移4位,ah中得到高4位的值
and al, 00001111B ; al 中为底 4 位的值
mov bl, ah
mov bh, 0
mov ah, table[bx] ; 用高 4 位的值作为相对于 table 的偏移,取得相对应的字符
mov bl, al
mov bh, 0
mov al, table[bx] ; 用低 4 位的值作为相对于 table 的偏移,取得相对应的字符
mov bx, 0B800H
mov es, bx
mov byte ptr es:[160 * 12 + 40 * 2 + 0], ah
mov byte ptr es:[160 * 12 + 40 * 2 + 1], 00000111B
mov byte ptr es:[160 * 12 + 40 * 2 + 2], al
mov byte ptr es:[160 * 12 + 40 * 2 + 3], 00000111B
pop es
pop bx
pop ax
ret
codesg ends
end start
; 方法2
assume cs:code
code segment
start:
mov al,0ABH
call showbyte
mov ax,4c00h
int 21h
; 子程序:
; 用al传送要显示的数据
showbyte:
jmp short show
table db '0123456789ABCDEF' ; 字符表
show: push bx
push es
mov ah,al
shr ah,1
shr ah,1
shr ah,1
shr ah,1 ; 右移4位,ah中得到高4位的值
and al,00001111b ; al中为低4位的值
mov bl,ah
mov bh,0
mov ah,table[bx] ; 用高4位的值作为相对于table的偏移,取得对应的字符 table[000A] = A = 41H
mov bx,0b800h
mov es,bx
mov es:[160*12+60*2],ah
mov bl,al
mov bh,0
mov al,table[bx] ; 用低4位的值作为相对于table的偏移,取得对应的字符 table[000B] = B = 42H
mov es:[160*12+60*2+2],al
pop es
pop bx
ret
code ends
end start
6. 计算 sin(x),使用直接定址表
; 编写一个子程序,计算 sin(x) = {0,30,60,90,120,150,180}
; 并在屏幕中间显示计算结果。比如 sin(30)显示为"0.5"
assume cs:codesg
codesg segment
start: mov ax, 0
mov al, 120
call sin
mov ax, 4c00h
int 21h
; ---------------------------------------------
sin: jmp _show ; 01 23 45 67 89 1011 1012
table dw ag0, ag30, ag60, ag90, ag120, ag150, ag180 ; 字符串偏移地址表
ag0 db '0', 0
ag30 db '0.5', 0
ag60 db '0.866', 0
ag90 db '1', 0
ag120 db '0.866', 0
ag150 db '0.5', 0
ag180 db '0', 0
_show: push bx
push es
push si
mov bx ,0B800H
mov es, bx
; 用 角度/30 作为相对于 table 的偏移,取得对应字符串的偏移地址,放在 bx 中
mov ah, 0
mov bl, 30
div bl
; 判断部分,如果是奇奇怪怪的角度直接退出
cmp ah, 0
jne _retShow
mov bl, al
mov bh, 0
add bx, bx ; 因为是 dw 类型的所以要 乘以2,一个偏移地址占 2 个字节
mov bx, table[bx] ; table[0008] = 2B
; 以下显示 sin(x) 对应字符串
mov si, 160 * 12 + 40 * 2
_shows: mov ah, cs:[bx]
cmp ah, 0
je _retShow
mov byte ptr es:[si + 0], ah
mov byte ptr es:[si + 1], 00001111B
inc bx
add si, 2
jmp short _shows
_retShow:pop si
pop es
pop bx
ret
codesg ends
end start