1. 判斷語句正確錯誤
1)、MOV BL, CX: 可行但mov的源比目標長度大,會導致數據丟失。警告:Operand types must match
2)、MOV DS, SS: 錯誤,ds是數據段寄存器,ss是棧寄存器,都屬于段寄存器。8086不支持段寄存器之間傳送數據。報錯:Wrong type of register
3)、MOV [BX], [DI]: 錯誤,不能從存儲單元到存儲單元。報錯: Improper operand type
4)、MOV AL, BX: 可行但mov的源比目標長度大,會導致數據丟失。警告:Operand types must match
5)、MOV ES, AL: 源不能比目標長度短,報錯:Wrong type of register
6)、MOV DS, DX: OK
7)、MOV CS, AX: 錯誤,CS不能作為目標寄存器。Illegal use of CS register
8)、MOV BX, CS:正確。
9)、MOV DS, 1230H: 錯誤,立即數不能直接送段寄存器。Immediate mode illegal
10)、MOVSX DS, AL: 錯誤,8086中不支持該指令。報錯: Expected: instruction or directive
11)、XCHG BX, 3: 寄存器間交換指令任何一個操作數不能是立即數。報錯: Immediate mode illegal
12)、POP CS: 不能POP CS段寄存器。報錯:llegal use of CS register
13)、MOV IP, SI:IP不能作為目標寄存器。報錯:Symbol not defined:IP
14)、PUSH CS: 正確
15)、PUSH BL: BL的大小不符合。警告:Illegal size for operand
16)、MOV [SP], BX: 正確
17)、MOV AX, BX+3: 錯誤,BX+3是一個值,不是內存地址指針。 報錯: Illegal use of register
18)、MOV AX, [BX+3]: 正確
19)、MOV BX, [BX]:正確
20)、MOV BH, [BL]:錯誤,BL不能作為內存地址。報錯:Must be index or base register
21)、XCHG ES, AX: 錯誤, XCHG操作任何一個操作數都不能為段寄存器。報錯:Improper use of segment register
22)、LEA AX, [BX+SI]:正確。
23)、MUL 10H: 錯誤,MUL的操作數不能是立即數。報錯:Immediate mode illegal
24)、IMUL DX, 10H:錯誤,IMUL只有一個操作數。警告:Extra characters on line
25)、DIV 10:錯誤,DIV的操作數不能是立即數。報錯:Immediate mode illegal
26)、IDIV DX, 10H:錯誤,IDIV只有一個操作數。警告:Extra characters on line
27)、SHL AX, CX:錯誤,移動位數要用1或者CL指示。報錯:Constant expected
28)、SHR BX, CH:錯誤,移動位數要用1或者CL指示。報錯:Constant expected
29)、ROL BX, 20:錯誤,循環左移的位數大于1時必須用CL指示。報錯:Improper operand type
30)、RCR AX, CL:正確
31)、CMP AX,1234H:正確
32)、CMP 12H, CL:錯誤,CMP第一個操作數不能是立即數。報錯:Immediate mode illegal
33)、JCXZ next:正確。
34)、JEBXZ next:錯誤: 8086中沒有該指令。報錯:Expected:instruction or directive。
2. 匯編程序
13.編寫一個程序,統計在雙字變量DDVAR的內容中二進制位是1的位數,并存入變量COUNT中
.model small
.datanum dd 0fffffffhnl EQU word ptr numnh EQU word ptr num+2count dw 0
.code
start:mov ax,@datamov ds,axmov ax,nl ;計算低16位1的個數call count1mov ax,nh ;計算高16位1的個數call count1mov dx,count ;將count放在dx寄存器中,便于調試觀察mov ax,4c00hint 21hcount1 proc nearmov cl,16
work:shl ax,1 ;左移1位,最高位放入cfjnc ctninc count ;cf為1則計數器加1
ctn:loop workret
count1 endpend start
15.編寫一個程序把字符串String兩端的空格刪除(字符串以0結束)。
.model small
.datastr db " Bow to Hungry. ",0EndOfString EQU 0 ;字符串尾標志Blank EQU 20h ;空格
.stack 200h
.code
start:mov ax,@datamov ds,axcall trimmov ax,4c00hint 21h;刪除字符串兩端的空格
trim proc nearlea bx,strlea ax,str;找到第一個非空格
pre:cmp byte ptr [bx],EndOfStringje exit cmp byte ptr [bx],Blankjne mvinc bxjmp pre;將非空格位置起的字符串前移
mv:push bxmov dl,[bx]mov bx,axmov [bx],dlinc axpop bxinc bxcmp byte ptr [bx],EndOfStringje sufjmp mv;從后向前找到最后一個非空格
suf:dec bxcmp byte ptr [bx],Blankjne prntjmp suf;輸出字符串
prnt:mov byte ptr [bx+1],'$'lea dx,strmov ah,9int 21h
exit:ret
trim endpend start
17.用雙重循環將下三角乘法表存入從Result開始的45字節中。
自己添加了輸出顯示。
.model small
.dataresult db 45 dup(?)tmp db 5 dup(0),'$' ;十進制輸出緩沖區buf EQU offset tmp+5 ;輸出緩沖區尾cr = 0dh ;回車符lf = 0ah ;換行符blk = 20h ;空格num = 9 ;循環次數
.stack 200h
.code
start:mov ax,@datamov ds,ax;將result地址放入B寄存器lea bx,result;也可以相對基址變址尋址方式 mov bx,0mov cl,num ;外層循環 9~1
for1:mov ax,cx ;內層循環 cx~9push cx ;保護外層循環的c寄存器
for2:push axmul cl ;計算 ax <- al*clmov word ptr [bx],ax;相對基址變址尋址方式 mov word ptr result[bx],axinc bxcall outputcall blankpop axinc axcmp ax,numjle for2pop cxcall endlloop for1mov ax,4c00hint 21h;輸出ax中的十進制數
output proc nearpush axpush bxpush cxpush dxmov bx,buf
outloop:or ax,axjz outloopfin ;ax為0則結束mov dx,0mov cx,10div cx ;dx:ax除以10,余數在dx中add dx,'0';轉換為字符dec bxmov byte ptr [bx],dljmp outloop
outloopfin:mov dx,bxmov ah,9int 21hpop dxpop cxpop bxpop axret
output endp;輸出換行
endl proc nearpush axpush dxmov dl,crmov ah,2int 21hmov dl,lfmov ah,2int 21hpop dxpop axret
endl endp;輸出空格
blank proc nearpush axpush dxmov dl,blkmov ah,2int 21hpop dxpop axret
blank endpend start
4.22分別編寫以下子程序實現下列功能(所有變量都是字類型)
1)ABS(x)=|x|
2) \(F(x)=3x^2+5x-8\)
3) strlen(String),(求字符串長度,字符串以0結束)
.model small
.datax dw -2z dw ?str db "sekai ichi kawaii.",0len dw 0
.stack 200h
.code
start:mov ax,@datamov ds,axcall absxmov ax,16mov x,axcall fcall strlenmov ax,4c00hint 21h
;ABS(x)
absx proc nearmov ax,xcmp ax,0jge doneneg ax
done:ret
absx endp; f(x)=3x^2+5x-8=(3x+5)*x-8
f proc nearpush axmov ax,3mul xadd ax,5mul xsub x,8mov z,axpop axret
f endpstrlen proc nearpush axpush bxlea bx,strmov ax,0
for:cmp byte ptr [bx],0je exitinc axinc bxjmp for
exit:mov len,axpop bxpop axret
strlen endp
end start
微機原理與接口技術習題4-31:
一個學生的信息包括姓名、班級、學號(班內序號)、成績。試編寫程序實現以下功能:
(1) 能錄入學生成績(十進制形式);
(2) 能按要求(如班內序號或成績)進行排序顯示;
(3) 能統計平均成績;
(4) 能按分數段統計人數,不及格、60~70、70~80、80~90、90~100各分數段的人 數。
寫得有點長。
origin: 11-12
UPD:2017-11-28 17:20:21 zjl發現了兩個bug,統計分數段時沒有清空以及90~100段有問題,已修復。
UPD: 2017-11-29 19:79 lzx 發現分數段還是不正確。經過思考,發現我當成排好序的了,然后寫過了個算法。另外注意,宏太長會導致一些跳轉失敗,jmp外的跳轉指令能跳轉的相對位置有限,所以要用子程序。
;=========================MACRO=======================
saveReg macropush axpush bxpush cxpush dxpush si
endmrecoverReg macropop sipop dxpop cxpop bxpop ax
endm; cx <- x*10
mul10 macro xpush axmov ax, xmov cx, 10imul cxmov cx, axpop ax
endm; change ax from string to decimal number
toDigit macromov dl, al ; ready to showsub al, '0'; ax-='0'mov ah, 0
endm; output '\n\r'
endl macrooutputChar CRoutputChar LF
endm; echo input
echoIn macromov ah, 01hint 21h
endm; ans <- x/10, ans <- x%10
getAns macro xsaveRegmov ax, xmov dx, 0mov cx, 10div cxmov ans, axmov ans2, dxrecoverReg
endm; output char
outputChar macro charpush axpush dxmov dl, charmov ah, 2int 21hpop dxpop ax
endm; output string ends with '$'
outputStr macro stringpush dxpush axlea dx, stringmov ah, 9int 21hpop axpop dx
endm; read until input is digit.
; store in [al]
readNonDigit macrolocal for
for:mov ah, 1; echo inputint 21hcmp al, '0'jb for ;<0cmp al, '9'ja for ;>9
endm; input string ends with '\n' or ' '
inputStr macro stringpush bxlea bx, stringcall inStrpop bx
endm; input number num
inputNum macro numpush cxcall inputNumPromov word ptr num, cxpop cx
endminputFloat macro numpush cxcall inputFloatPromov word ptr num,cxpop cx
endm; output num
outputNum macro numpush axmov ax, word ptr numcall outputNumPropop ax
endm; stumov dest,souce
;function: mov student from souce to dest
stumov macro dest,soucesaveRegmov ax, dsmov es, ax; (es)<-(ds)lea si, soucelea di, destmov cx, stuSizeshr cx, 1cld;df<-0rep movswrecoverReg
endm; stage
stage macrolocal begin,end,clearNumFor,for,for2,next,showsaveReg;clear nummov bx,0
clearNumFor:cmp bx,10jae beginmov num[bx],0add bx,2jmp clearNumFor
begin:mov ax, 0mov bx, 0
for:cmp ax, nje showmov cx, 600mov dx, 0
for2:cmp word ptr stus[bx].score, cxjb next; <600cmp cx, 1000je next; == 1000add cx,100add dx,2jmp for2
next:inc axpush bxmov bx,dxinc num[bx]pop bxadd bx, stuSizejmp forshow:outputNum num[0]mov bx, 2
nextShow:cmp bx, 10je endoutputChar ','outputNum num[bx]add bx, 2jmp nextShow
end:endlrecoverReg
endm; swap stua,stub
;function: swap student stua and student stub
swap macro stua,stubstumov tmp,stuastumov stua,stubstumov stub,tmp
endmclr macro mov ah, 0mov al, 03hint 10h
endmPressAny macromov ah, 08hint 21h
endm;=========================BEGIN=======================
.model small
.datastudent strucnm db 10 dup('$')clss db 10 dup('$')id dw ?score dw ?student endsstus student 10 dup(<>)tmp student <>stuSize EQU $-tmpn dw 0ans dw 0ans2 dw 0sum dw 0num dw 6 dup(0)op dw 0hasNum db 0cmpById db 0buf db 6 dup(0), '$'bufptr EQU offset buf+6
.constCR = 0dhLF = 0ahBLK = ' 'DOT = '.'EN_NUM db "Enter the number of students:", '$'EN_DETAIL db "Enter name, class, id and score of each student:",CR,LF, '$'EN_MENU db "MENU:",CR,LFdb "0: exit",CR,LFdb "1: sort by score", CR,LFdb "2: sort by id", CR,LFdb "3: get average score", CR,LFdb "4: get the number of students in each stage",CR,LF,'$'EN_AV db "The average score is:",'$'EN_TH db "Name Class Id Score",CR,LF,'$'EN_PRS db "Press any key to return...",'$'EN_ST db "[0,60),[60,70),[70,80),[80,90),[90,100]",CR,LF,'$'
.stack 300h
.code
start:mov ax, @datamov ds, axclroutputStr EN_NUMinputNum noutputStr EN_DETAILmov cx, nmov bx,0or cx,cxjz MENU
;===================readStu==============
readStu:inputStr stus[bx].nminputStr stus[bx].clssinputNum stus[bx].idinputFloat stus[bx].scoremov ax, word ptr stus[bx].scoreadd sum, axadd bx,stuSizeloop readStu
;==================Menu==============
MENU:outputStr EN_MENUinputNum opcmp op, 0jne nxOpjmp exit
nxOp:cmp op, 2je sortByIdcmp op, 3je averageScorecmp op, 4je everyStage
;=====[ sortByScore ]============
sortByScore:outputStr EN_THmov cmpById, 0call sortjmp PRESS
;=====[ sortById ]============
sortById:outputStr EN_THmov cmpById, 1call sortjmp PRESS
;====[ averageScore ]============
averageScore:outputStr EN_AVmov ax, summov dx, 0or n, 0jz sishewurudiv nshl dx, 1cmp dx, njb sishewuruinc ax
sishewuru:getAns axcall outputAnsjmp PRESS
;====[ everyStage ]==============
everyStage:outputStr EN_STstage
PRESS:outputStr EN_PRSPressAnyclrjmp MENU
exit:mov ax, 4c00hint 21h;=============outputNumPro==============
; output a decimal number from ax
outputNumPro proc nearsaveRegmov bx, bufptror ax, axjnz outLoopdec bxmov byte ptr [bx], '0'jz show
outLoop:or ax, axjz showmov dx, 0mov cx, 10div cxadd dx, '0'dec bx mov byte ptr [bx], dljmp outLoop
show:mov dx, bxmov ah, 9int 21hrecoverRegret
outputNumPro endp
;===================outputAns==============
outputAns proc nearoutputNum ansor ans2, 0je ansEndoutputChar DOToutputNum ans2
ansEnd:endlret
outputAns endp;==================outputFun====================
; output
output proc nearpush axpush bxpush cxmov bx, 0mov cx, n
for:outputStr stus[bx].nmoutputChar BLKoutputStr stus[bx].clssoutputChar BLKoutputNum stus[bx].idoutputChar BLKmov ax, word ptr stus[bx].scoregetAns axcall outputAnsadd bx, stuSizeloop for
return:pop cxpop bxpop axret
output endp
;===========Sort===============
;sort
sort proc nearsaveRegmov dx, 1
for1:cmp dx, njne ctnjmp done ;jmp can jump far
ctn:mov cx, 1mov ax, nsub ax, dx; n-1..1mov bx, 0push dxmov dx, 0
for2:cmp dx, axjne ctn2jmp next
ctn2:push axor cmpById, 0jz sScojmp sId
sSco:mov ax, word ptr stus[bx].scorecmp ax, word ptr stus[bx+stuSize].scorejmp by
sId:mov ax, word ptr stus[bx].idcmp ax, word ptr stus[bx+stuSize].id
by:pop axjbe nex2swap stus[bx], stus[bx+stuSize]mov cx, 0
nex2:inc dxadd bx, stuSizejmp for2
next:pop dxinc dxcmp cx, 1je donejmp for1
done:call outputrecoverRegret
sort endp;=============inputFloatPro==============
; input xx.x or xx
; cx <- xx.x * 10
inputFloatPro proc nearpush dxpush bxpush axreadNonDigitmov bx, 0mov cx, 0
whileDigit:cmp al, '0'jb middle ;<0cmp al, '9'ja middle ;>9mov bx, 1mul10 cx; cx=cx*10jo inFEndtoDigitadd cx, ax; cx+=axjo inFEnd
diNext:echoInjmp whileDigit
middle:mul10 cx; cx=cx*10jo inFEndcmp bx, 1jne inFEndcmp al, '.'jne inFEnd
lastdigit:echoIncmp al, '0'jb inFEnd ;<0cmp al, '9'ja inFEnd ;>9toDigitadd cx, ax; cx+=ax
over:echoIncmp al, CRje inFEndcmp al, BLKje inFEndjmp over
inFEnd:pop axpop bxpop dxret
inputFloatPro endp;=============inputNumPro==============
; input a decimal num to [cx]
inputNumPro proc nearpush axpush bxreadNonDigitmov cx, 0
inDecLoop:cmp al, '0'jb inEnd ;<0cmp al, '9'ja inEnd ;>9mul10 cx; cx=cx*10jo inEndtoDigitadd cx, ax; cx+=axjo inEnd
inNext:echoInjmp inDecLoop
inEnd:pop bxpop axret
inputNumPro endp;=================inStr==================
; input string ends with '\n' or ' ' to [bx]
inStr proc nearpush ax
inStrLoop:echoIncmp al, CRje inStrEndcmp al, BLKje inStrEndmov byte ptr [bx],alinc bxjmp inStrLoop
inStrEnd:mov byte ptr [bx],'$'pop axret
inStr endp
end start
(實驗)可編程并行接口8255 方式0
code segmentassume cs:code
start:mov dx, 28bhmov al, 10001001b out dx, al
inout: mov dx, 28ah ;從C口輸入數據in al, dxmov dx, 288h ;從A口輸出out dx, almov ah,01hint 16hjz inout ;循環mov ax, 4c00hint 21h
code ends
end start
串口通訊8251
.model small
.datamsg db 'You can play a key on the keyboard~',0ah,0dh,'$'control_port8254 EQU 283hdata0_port8254 EQU 280hcontrol_port8251 EQU 2b9hdata_port8251 EQU 2b8h
.codeassume cs:@code,ds:@data
start:mov ax,@datamov ds,axmov dx,control_port8254 ;8254初始化mov al,00010110b ;8254 計數器0工作在方式3out dx,almov dx,data0_port8254 ;將初值寫入計數器0mov al,52out dx,almov dx,control_port8251 ;8251初始化mov al,01000000b ;復位命令字out dx,alnop ;延時mov al,01001110b ;方式控制字(異步方式,字長8,無校驗,波特率因子16)out dx,almov al,00100111b ;工作命令字(RTS,ER,RXE,DTR,TXEN置1)out dx,allea dx,msg ;提示信息mov ah,09hint 21hfor1: mov dx,control_port8251 ;TxRDY為1?in al,dxtest al,01hjz for1for2: mov ah,01 ;讀鍵盤int 21hcmp al,27 ;是否是ESCjz exitinc almov dx,data_port8251out dx,alfor3: mov dx,control_port8251 ;DxRDY為1?in al,dxtest al,02hjz for3mov dx,data_port8251 ;從8251數據口接收數據in al,dxmov dl,almov ah,02 ;顯示數據int 21hjmp for1exit: mov ax,4c00h ;返回操作系統int 21h
end start
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎
總結
以上是生活随笔為你收集整理的汇编笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。