Bootstrap

《IBM-PC汇编语言程序设计 第二版》部分习题答案(第5章)

 

现在部分学校用的还是这本书,清华大学出版社,沈美明、温冬婵编著。
   这当然不是标准答案,自己做的,呵呵,希望对大家有用处。

5.1 试编写一个汇编语言程序,要求对键盘输入的小写字母用大写字母显示出来
.model small
.stack 100H
.code
main proc far
Start:
 push dx
 mov ax,0
 push ax
 
 mov ah,01H
 int 21H
 
 cmp al,61H
 
 jl lop1
 
 cmp al,7BH
 jge lop1
 
 sub al,20H
 mov dl,al
 
 lop1:mov ah,2
 int 21H
 
 ret
End start

5.2 编写一个程序,从键盘接受一个小写字母,然后找出它的前导字符和后续字符,再按顺序显示这三个字符.
.model small
.386
.code
MAIN PROC FAR
start:
 push ds
 sub ax,ax
 push ax
 
input:
 mov ah,7H
 int 21H
cmpe:
 
 cmp al,20H
 JE  exit
 
 cmp al,61H
 JL  input
 
 cmp al,7AH
 JG  input
print:
 sub al,01H
 mov dl,al
 mov ah,02H
 int 21H
 
 add al,01H
 mov dl,al
 mov ah,02H
 int 21H
 
 add al,01H
 mov dl,al
 mov ah,02H
 int 21H
 
 ;输出换行回车
 mov dl,0AH
 mov ah,02H
 int 21H

 jmp input
exit :
 ret
MAIN ENDP
END start

5.3 将AX寄存器中的16位数分成4组,每组4位,然后把这四组数分别放在AL、BL、CL、DL中。
.model small
.data
x DB 4 dup(?)
.stack 100H
.code
MAIN PROC FAR
start:
 push ds
 and ax,00H
 push ax
 
 mov ax,1234H
 
 mov cx,04H
 mov si,00H
lop:
 push cx
 mov  cl,04H
 rol ax,cl
 push ax
 and al,0FH
 mov BYTE PTR x[si],al
 pop ax
 pop cx
 add si,2
 Loop lop
 mov al,[X]
 mov bl,[X+2]
 mov cl,[X+4]
 mov dl,[X+6]
print:
 mov ah,02H
 int 21H
 
 mov dl,al
 mov ah,02H
 int 21H
 
 mov dl,bl
 mov ah,02H
 int 21H

 mov dl,cl
 mov ah,02H
 int 21H
exit:
 ret
MAIN ENDP
END start

5.4 编写一个程序,要求比较两个字符串STRING1和STRING2所含字符是否相同,若相同则显示"MATCH",若不同在显示:"NO MATCH"。

.model small
.data
STRING1 DB 'I must study hard'
STRING2 DB 'I must study hard'
X       DB 'MATCH .$'
Y       DB 'NO MATCH.$'

.stack 100H
.code
main proc far
Start:
 push dx
 mov ax,0
 push ax
 
 mov ax,@data
 mov ds,ax
 mov es,ax
 
 lea si,STRING1
 lea di,STRING2
 cld
 
 mov cx,(string2-string1)/ type STRING2
 ret
End start

5.5编写一个程序,要求能从键盘接收一个个位数N,然后响铃N次,(响铃的ASCII为07)。
这题比较有意思,呵呵。
model small

.code
main proc far
start:
 push ds
 sub ax,ax
 push ax
input:
         mov ah,01H
         int 21H

         cmp al,20H
         je  exit

         cmp al,30H
         jle input
         cmp al,3AH
         jge input
         sub al,30H
         mov cx,ax
         and cx,0FFH
lop:
         mov dl,07H
         mov ah,2H
         int 21H
         loop lop
         jmp input
exit :
         ret

main endp
end start

5.6编写程序,将一个包含有20个数据的数组M分成两个数组:正数数组和负数数组N,并分别把这两个数组中的数据个数显示出来。
.model small
.386
.data
M DB 1,2,3,4,5,6,7,8,9,10,-1,-2,-3,-4,-5,-6,-7,-8,-9,-10
P DB 20 dup(?)
N DB 20 dup(?)
.code
MAIN PROC FAR
start:
  PUSH ds
  AND  ax,0
  PUSH ax
  
  MOV  ax,@data
  mov  ds,ax
  MOV  bx,0
  MOV  si,0
  MOV  di,0
  MOV  cx,20D
  
cmpe  :
  CMP  M[bx],0
  JL  ifLow
hight :
  MOV  al,byte ptr M[bx]
  MOV  byte ptr P[si],al
  inc  si
  JMP  commonContrl
ifLow :
  MOV  al,byte ptr M[bx]
  MOV  byte ptr N[di],al
  INC  di
commonContrl:
  INC  bx
  loop cmpe
  mov  ax,si
  call showNumber
  call printCR
  mov  ax,di
  call showNumber
exit: ret
MAIN ENDP
;;;;;;;;;;;;;;;;;注意,ShowNumber这个子过程有问题,请自行修改;;;;;;;;;;;;;;;;
showNumber PROC NEAR
covernum:
  DAA
  MOV  dx,ax
  MOV  cl,2H
show:
  ROL  dl,4H
  push dx
  AND  dl,0fH
  ADD  dl,30H
  MOV  ah,02H
  int  21H
  pop  dx
  loop show
  ret
showNumber ENDP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
printCR PROC NEAR
  mov dl,0aH
  mov ah,02H
  int 21H
  mov dl,0dH
  mov ah,02H
  int 21H
  ret
printCR ENDP

end start

5.7编制一个汇编语言程序,求出首地址为DATA的100D字数组中的最小偶数,并把它放在AX中。
     此题根据题意要求应该使用完整汇编格式,因为精简格式也使用DATA....

dataare segment
DATA DW 3322H,4555H,200H,3544H,1245H
num  DB ($-DATA)/2
dataare ends

code segment

assume cs:code,ds:dataare

MAIN PROC FAR
start:
  push ds
  mov  ax,0H
  push ax
  
  mov  ax,dataare
  mov  ds,ax
  mov  dx,0H               ;偶数数量计数
  mov  cx,Word ptr [num]
  mov  si,0H
isO:
  mov  bx,WORD PTR DATA[si]
  shr  bx,1H
  jnc  addDX
  jmp  commonControl
addDX:
  ADD  dx,1H
  cmp  dx,1H
  je   firstAXValue
compare:
  mov  bx,WORD PTR DATA[si]
  cmp  bx,ax
  jge  commonControl
  mov  ax,bx
commonControl:
  ADD  si,2H
  loop isO
  jmp  exit
firstAXvalue:
  mov ax,WORD PTR DATA[si]
  jmp compare
exit:
  ret
MAIN ENDP
code ends
END start
5.8没有做。。
5.9编写一个汇编语言程序,要求从键盘上接收一个思维的十六位进制数,并在终端上显示与它等值的二进制数。
.model small
.386
.code
main proc far
start:
 push ds
 mov  ax,0
 push ax 
 mov  ax,0
 mov  cx,4
 mov  dx,0
input:
 mov  ah,1H
 int  21H
 cmp  al,30H
 jl   input
    cmp  al,39H
    jle  s
 cmp  al,61H
 jl   input
 cmp  al,66H
 jg   input
 sub  al,27H
s:
 sub  al,30H
 add  dl,al
 cmp  cx,1H
 je   f
 rol  dx,4
 
f:
 loop input
exit:
 call print
 ret
main endp

print proc near
 mov cx,10H
p:
             rol  dx,1
 push dx
 and  dx,1
 add  dx,30H
 mov  ah,2
 int  21H
 pop  dx
 loop p
ret
print endp
end start
 
5.10设有一段英文,其变量字符名为ENG,并以$字符结束。试编写一程序,查对单词SUN在该文中的出现次数,并以格式"SUN XXXX"显示出次数。
.model small
.386
.data
 ENG     db 'SUN's SUN JAVA',24H  ;;;;24H = $
 MESSAGE db 'SUN:','$'
.stack 100H
.code
MAIN PROC FAR
start:
  PUSH DS
  AND  AX,0
  PUSH AX
  
  MOV  AX,@data
  MOV  DS,AX
  ;------------------------
  MOV  AX,0H
  MOV  SI,1H
subSI1:
  SUB  SI,1H
subSI2:
  SUB  SI,1H
compareS:
  ADD  SI,1H
  MOV  DL,ENG[SI]
  CMP  DL,24H
  JE   print
  CMP  DL,53H
  JNE  compareS
compareU:
  ADD  SI,1H
  MOV  DL,ENG[SI]
  CMP  DL,55H
  JNE  subSI2
compareN:
  ADD  SI,1H
  MOV  DL,ENG[SI]
  CMP  DL,4EH
  JNE  subSI1
  INC  AX
  JMP  compares
print:
  LEA  DX,MESSAGE
  PUSH AX
  MOV  AH,09H
  INT  21H
  POP  AX
  call showNumber
exit:
  ret
MAIN ENDP
;;;;;;;;;;;;;;;;;注意,ShowNumber这个子过程有问题,请自行修改;;;;;;;;;;;;;;;;
showNumber PROC NEAR
covernum:
  DAA
  MOV  dx,ax
  MOV  cl,4H
show:
  ROL  dx,4H
  push dx
  AND  dx,0fH
  ADD  dx,30H
  MOV  ah,02H
  int  21H
  pop  dx
  loop show
  ret
showNumber ENDP
END start 

5.11从键盘输入一系列以$为结束副的字符串,然后对其中的非数字字符计数,并显示出计数结果。
.model small
.386
.code
MAIN PROC FAR
start:
  push ds
  mov  ax,0
  push ax
  
  mov  cx,0
input:
  mov  ah,1H
  int  21H
compare:
  cmp  al,24H
  je   print
  cmp  al,30H
  jl   addCount
  cmp  al,39H
  jg   addCount
addCount:
  add  ax,1H
  jmp  input
print:
  call showNumber
exit: ret
MAIN ENDP
;;;;;;;;;;;;;;;;;注意,ShowNumber这个子过程有问题,请自行修改;;;;;;;;;;;;;;;;
showNumber PROC NEAR
covernum:
  DAA
  MOV  dx,ax
  MOV  cl,2H
show:
  ROL  dl,4H
  push dx
  AND  dl,0fH
  ADD  dl,30H
  MOV  ah,02H
  int  21H
  pop  dx
  loop show
  ret
showNumber ENDP
END start

5.12 有一个首地址为MEM的100D字数组,试编制程序删除数组中所有为零的项,并将后续项向前压缩,最后将数组的剩余部分补上零。
.model small
.386
.stack 100H
.data
mem dw 12,0,0,0,0,0,1,2,3,6,4,7,8,2,1,0,0,54,5,0,2,4,7,8,0,5,6,2,1,4,8,5,1,45,7,5,1,2,0,2,4,0,2,54,0,12,0,0,0,0,0,1,2,3,6,4,7,8,2,1,0,0,54,5,0,2,4,7,8,0,5,6,2,1,4,8,5,1,45,7,5,1,2,0,2,4,0,2,54,0,45,7,5,1,2,0,2,4,0,2
.code
MAIN PROC FAR
start:
  push ds
  and  ax,0
  push ax
  
  mov  ax,@data
  mov  ds,ax
;----------------------
  mov  ax,0H
  mov  bx,64H
  mov  cx,64H
  mov  si,0FFFEH
repeat:
  ADD  si,2H
  cmp  MEM[si],0H
  JE   calls
  loop repeat
calls:
  INC  ax
  call sort
  cmp  ax,1H
  JE   lastValue
  DEC  cx
  jmp  repeat
exit :
  ret
lastValue:
  mov  mem[bx],0H
  DEC  cx
  jmp  repeat
  
MAIN ENDP

sort PROC NEAR
 push cx
 push si
 sub  si,2H
s:
 add  si,2H
 mov  dx,mem[si]
 mov  mem[si+2],dx
 loop s
return:
 pop si
 pop cx
 ret
sort ENDP
END start


作者Blog: http://blog.csdn.net/phpsessid/
;