汇编语言程序设计(三)
w88 石光 981239 第一题源程序
code segment
assume cs:code,ds:code
.386p
start proc near
jmp next
gdtadds
dw 001fh,0000h,0000h
gdttab
db 000h,000h,00h,00h,00h,00h,00h,00h
db 0ffh,0ffh,00h,00h,00h,9bh,00h,00h
db 0ffh,0ffh,00h,00h,00h,93h,00h,00h
db 0ffh,0ffh,00h,80h,0bh,93h,00h,00h
errmsg db 'You must run this program in real mode!',0dh,0ah,'$'
msg_1 db 'red word,green background.'
count_1 equ $-msg_1
attr_1 db 24h
msg_2 db 'red word,green background.'
count_2 equ $-msg_2
attr_2 db 42h
msg_3 db 'highlighted red word,blink green background.'
count_3 equ $-msg_3
attr_3 db 0cah
back db 0dh,0ah,'Back in Real Mode!$'
next: mov ax,cs
mov ds,ax
mov eax,cr0
and al,1
je begin
lea dx,errmsg
mov ah,9
int 21h
mov ah,4ch
int 21h
begin:
xor eax,eax
xor ebx,ebx
mov ax,cs
shl eax,04h
mov bx,offset gdttab
add eax,ebx
mov di,offset gdtadds+02h
mov cs:[di],eax
xor eax,eax
xor ebx,ebx
mov ax,cs
shl eax,04h
mov di,offset gdttab+08h
mov si,offset gdttab+10h
mov cs:[di+02h],ax
mov cs:[si+02h],ax
shr eax,10h
mov cs:[di+04h],al
mov cs:[si+04h],al
mov cs:[di+07h],ah
mov cs:[di+07h],ah
cli
lgdt fword ptr cs:gdtadds
mov eax,cr0
or al,01h
mov cr0,eax
jmp protection_mode
protection_mode:
mov ax,0010h
mov ds,ax
mov si,offset msg_1
mov ax,0018h
mov es,ax
mov ax,0010h
mov ds,ax
mov di,0000h
cld
mov ah,attr_1
mov cx,count_1
L1:
lodsb
stosw
loop L1
mov ah,attr_2
mov cx,count_2
L2:
lodsb
stosw
loop L2
mov ah,attr_3
mov cx,count_3
L3:
lodsb
stosw
loop L3
mov eax,cr0
and al,0feh
mov cr0,eax
jmp return_real_mode
return_real_mode:
sti
mov ax,cs
mov ds,ax
mov dx,offset back
mov ah,09
int 21h
mov ax,4cffh
int 21h
start endp
code ends
end start

--------------------------------------------------------------------------------------------------------
;第二题源程序
.model small
.386p
.data
snake db ' -============#';字符串的第一个字符为空格;下为存放各字符位置向量的循环队列
pos db 21h,0ch,22h,0ch,23h,0ch
db 24h,0ch,25h,0ch,26h,0ch
db 27h,0ch,28h,0ch,29h,0ch
db 2ah,0ch,2bh,0ch,2ch,0ch
db 2dh,0ch,2eh,0ch,2fh,0ch;循环队列的队尾标记
tail db 0
.stack 100
.code
.startup;蓝色清屏
mov al,0
mov bh,10h
mov ah,6
mov cx,0
mov dl,79
mov dh,24
int 10h;用si指向当前蛇尾位置向量
lea si,pos;显示当前位置的蛇
L0: xor ch,ch
mov cl,15
lea di,snake;设置当前位置光标
L1: mov dh,[si+1]
mov dl,[si]
mov bh,0
mov ah,2
int 10h
;显示光标位置字符
mov bh,0
mov al,[di]
push cx
mov cx,1
mov bl,1eh
mov ah,9
int 10h
pop cx
inc di
inc si
inc si
cmp si,offset tail
jne A1
lea si,pos
A1: loop L1;用di指向当前蛇头位置向量;用bx指向原蛇头位置向量;用cx指向原蛇颈位置向量;(若当前蛇头与蛇颈位置相同,说明蛇转向180度);以上三个指针均为循环指针
mov di,si
mov bx,di
cmp bx,offset pos
jne A2
lea bx,tail
A2: sub bx,2
mov cx,bx
cmp cx,offset pos
jne A3
lea cx,tail
A3: sub cx,2;当前蛇尾位置向量前移一个
inc si
inc si
cmp si,offset tail
jne J0
lea si,pos;接受键盘输入
J0: mov ah,0
int 16h
cmp ah,72
jne J1;输入为上移
;将原蛇头位置向量处理后写入当前蛇头位置向量
mov al,[bx]
mov [di],al
mov al,[bx+1]
dec al;判断是否超出屏幕;若是,则从下方进入
cmp al,-1
jne M0
mov al,24
M0: mov [di+1],al
;比较当前蛇头位置向量和用原蛇颈位置向量
;(若当前蛇头与蛇颈位置相同,;说明蛇转向180度,不响应此输入)
mov al,[di]
xchg cx,bx
mov dh,[bx]
cmp al,dh
jne L0
mov al,[di+1]
mov dh,[bx+1]
cmp al,dh
jne L0
xchg cx,bx
jmp J0
J1: cmp ah,80
jne J2;输入为下移
mov al,[bx]
mov [di],al
mov al,[bx+1]
inc al
cmp al,26
jne M1
mov al,0
M1: mov [di+1],al
mov al,[di]
xchg cx,bx
mov dh,[bx]
cmp al,dh
jne L0
mov al,[di+1]
mov dh,[bx+1]
cmp al,dh
jne L0
xchg cx,bx
jmp J0
J2: cmp ah,75
jne J3;输入为左移
mov al,[bx+1]
mov [di+1],al
mov al,[bx]
dec al
cmp al,-1
jne M2
mov al,79
M2: mov [di],al
mov al,[di]
xchg cx,bx
mov dh,[bx]
cmp al,dh
jne L0
mov al,[di+1]
mov dh,[bx+1]
cmp al,dh
jne L0
xchg cx,bx
jmp J0
J3: cmp ah,77
jne J4;输入为右移
mov al,[bx+1]
mov [di+1],al
mov al,[bx]
inc al
cmp al,80
jne M3
mov al,0
M3: mov [di],al
mov al,[di]
xchg cx,bx
mov dh,[bx]
cmp al,dh
jne L0
mov al,[di+1]
mov dh,[bx+1]
cmp al,dh
jne L0
xchg cx,bx
jmp J0;输入为PageDown,则退出
J4: cmp ah,81
je FIN
jmp J0
FIN:
.exit
end