汇编笔记

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
.data
    num dd 0fffffffh
    nl EQU word ptr num
    nh EQU word ptr num+2
    count dw 0
.code
start:
    mov ax,@data
    mov ds,ax
    mov ax,nl ;计算低16位1的个数
    call count1

    mov ax,nh ;计算高16位1的个数
    call count1

    mov dx,count ;将count放在dx寄存器中,便于调试观察
    mov ax,4c00h
    int 21h

count1 proc near
    mov cl,16
work:
    shl ax,1 ;左移1位,最高位放入cf
    jnc ctn
    inc count ;cf为1则计数器加1
ctn:loop work
    ret
count1 endp

end start

15.编写一个程序把字符串String两端的空格删除(字符串以0结束)。


.model small
.data
    str db "   Bow to Hungry.    ",0
    EndOfString EQU 0 ;字符串尾标志
    Blank EQU 20h ;空格
.stack 200h
.code
start:
    mov ax,@data
    mov ds,ax

    call trim

    mov ax,4c00h
    int 21h

;删除字符串两端的空格
trim proc near
    lea bx,str
    lea ax,str

;找到第一个非空格
pre:
    cmp byte ptr [bx],EndOfString
    je exit 
    cmp byte ptr [bx],Blank
    jne mv
    inc bx
    jmp pre

;将非空格位置起的字符串前移
mv:
    push bx
    mov dl,[bx]
    mov bx,ax
    mov [bx],dl
    inc ax
    pop bx
    inc bx
    cmp byte ptr [bx],EndOfString
    je suf
    jmp mv

;从后向前找到最后一个非空格
suf:
    dec bx
    cmp byte ptr [bx],Blank
    jne prnt
    jmp suf

;输出字符串
prnt:
    mov byte ptr [bx+1],'$'
    lea dx,str
    mov ah,9
    int 21h
exit:
    ret
trim endp

end start

17.用双重循环将下三角乘法表存入从Result开始的45字节中。
自己添加了输出显示。

.model small
.data
    result 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,@data
    mov ds,ax

    ;将result地址放入B寄存器
    lea bx,result
        ;也可以相对基址变址寻址方式 mov bx,0
    mov cl,num ;外层循环 9~1
for1:
    mov ax,cx ;内层循环 cx~9
    push cx ;保护外层循环的c寄存器
for2:
    push ax
    mul cl ;计算 ax <- al*cl
    mov word ptr [bx],ax
        ;相对基址变址寻址方式 mov word ptr result[bx],ax
    inc bx

    call output
    call blank

    pop ax
    inc ax
    cmp ax,num
    jle for2
    pop cx
    call endl
    loop for1

    mov ax,4c00h
    int 21h

;输出ax中的十进制数
output proc near
    push ax
    push bx
    push cx
    push dx

    mov bx,buf
outloop:
    or ax,ax
    jz outloopfin ;ax为0则结束
    mov dx,0
    mov cx,10
    div cx  ;dx:ax除以10,余数在dx中
    add dx,'0';转换为字符
    dec bx
    mov byte ptr [bx],dl
    jmp outloop
outloopfin:
    mov dx,bx
    mov ah,9
    int 21h
    pop dx
    pop cx
    pop bx
    pop ax
    ret
output endp

;输出换行
endl proc near
    push ax
    push dx
    mov dl,cr
    mov ah,2
    int 21h
    mov dl,lf
    mov ah,2
    int 21h
    pop dx
    pop ax
    ret
endl endp

;输出空格
blank proc near
    push ax
    push dx
    mov dl,blk
    mov ah,2
    int 21h
    pop dx
    pop ax
    ret
blank endp

end start

4.22分别编写以下子程序实现下列功能(所有变量都是字类型)
1)ABS(x)=|x|
2) \(F(x)=3x^2+5x-8\)
3) strlen(String),(求字符串长度,字符串以0结束)

.model small
.data
    x dw -2
    z dw ?
    str db "sekai ichi kawaii.",0
    len dw 0
.stack 200h
.code
start:
    mov ax,@data
    mov ds,ax

    call absx

    mov ax,16
    mov x,ax
    call f

    call strlen

    mov ax,4c00h
    int 21h
;ABS(x)
absx proc near
    mov ax,x
    cmp ax,0
    jge done
    neg ax
done:
    ret
absx endp

; f(x)=3x^2+5x-8=(3x+5)*x-8
f proc near
    push ax

    mov ax,3
    mul x

    add ax,5
    mul x
    sub x,8
    mov z,ax

    pop ax
    ret
f endp

strlen proc near
    push ax
    push bx
    lea bx,str
    mov ax,0
for:
    cmp byte ptr [bx],0
    je exit
    inc ax
    inc bx
    jmp for
exit:
    mov len,ax
    pop bx
    pop ax
    ret
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 macro
    push ax
    push bx
    push cx
    push dx
    push si
endm

recoverReg macro
    pop si
    pop dx
    pop cx
    pop bx
    pop ax
endm

; cx <- x*10
mul10 macro x
    push ax
    mov ax, x
    mov cx, 10
    imul cx
    mov cx, ax
    pop ax
endm

; change ax from string to decimal number
toDigit macro
    mov dl, al ; ready to show
    sub al, '0'; ax-='0'
    mov ah, 0
endm

; output '\n\r'
endl macro
    outputChar CR
    outputChar LF
endm

; echo input
echoIn macro
    mov ah, 01h
    int 21h
endm

; ans <- x/10,  ans <- x%10
getAns macro x
    saveReg
    mov ax, x
    mov dx, 0
    mov cx, 10
    div cx
    mov ans, ax
    mov ans2, dx
    recoverReg
endm

; output char
outputChar macro char
    push ax
    push dx
    mov dl, char
    mov ah, 2
    int 21h
    pop dx
    pop ax
endm

; output string ends with '$'
outputStr macro string
    push dx
    push ax
    lea dx, string
    mov ah, 9
    int 21h
    pop ax
    pop dx
endm

; read until input is digit.
; store in [al]
readNonDigit macro
    local for
for:
    mov ah, 1; echo input
    int 21h
    cmp al, '0'
    jb for ;<0
    cmp al, '9'
    ja for ;>9
endm

; input string ends with '\n' or ' '
inputStr macro string
    push bx
    lea bx, string
    call inStr
    pop bx
endm

; input number num
inputNum macro num
    push cx
    call inputNumPro
    mov word ptr num, cx
    pop cx
endm

inputFloat macro num
    push cx
    call inputFloatPro
    mov word ptr num,cx
    pop cx
endm

; output num
outputNum macro num
    push ax
    mov ax, word ptr num
    call outputNumPro
    pop ax
endm

; stumov dest,souce
;function: mov student from souce to dest
stumov macro dest,souce
    saveReg
    mov ax, ds
    mov es, ax; (es)<-(ds)
    lea si, souce
    lea di, dest
    mov cx, stuSize
    shr cx, 1
    cld;df<-0
    rep movsw
    recoverReg
endm

; stage
stage macro
    local begin,end,clearNumFor,for,for2,next,show
    saveReg
    ;clear num
    mov bx,0
clearNumFor:
    cmp bx,10
    jae begin
    mov num[bx],0
    add bx,2
    jmp clearNumFor
begin:
    mov ax, 0
    mov bx, 0
for:
    cmp ax, n
    je show
    mov cx, 600
    mov dx, 0
for2:
    cmp word ptr stus[bx].score, cx
    jb next; <600
    cmp cx, 1000
    je next; == 1000
    add cx,100
    add dx,2
    jmp for2
next:
    inc ax
    push bx
    mov bx,dx
    inc num[bx]
    pop bx
    add bx, stuSize
    jmp for

show:
    outputNum num[0]
    mov bx, 2
nextShow:
    cmp bx, 10
    je end
    outputChar ','
    outputNum num[bx]
    add bx, 2
    jmp nextShow
end:
    endl
    recoverReg
endm

; swap stua,stub
;function: swap student stua and student stub
swap macro stua,stub
    stumov tmp,stua
    stumov stua,stub
    stumov stub,tmp
endm

clr macro 
    mov ah, 0
    mov al, 03h
    int 10h
endm

PressAny macro
    mov ah, 08h
    int 21h
endm

;=========================BEGIN=======================
.model small
.data
    student struc
        nm db 10 dup('$')
        clss db 10 dup('$')
        id dw ?
        score dw ?
    student ends
    stus student 10 dup(<>)
    tmp student <>
    stuSize EQU $-tmp
    n dw 0
    ans dw 0
    ans2 dw 0
    sum dw 0
    num dw 6 dup(0)
    op dw 0
    hasNum db 0
    cmpById db 0
    buf db 6 dup(0), '$'
    bufptr EQU offset buf+6
.const
    CR = 0dh
    LF = 0ah
    BLK = ' '
    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,LF
            db "0: exit",CR,LF
            db "1: sort by score", CR,LF
            db "2: sort by id", CR,LF
            db "3: get average score", CR,LF
            db "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, @data
    mov ds, ax
    clr
    outputStr EN_NUM
    inputNum n
    outputStr EN_DETAIL
    mov cx, n
    mov bx,0
    or cx,cx
    jz MENU
;===================readStu==============
readStu:
    inputStr stus[bx].nm
    inputStr stus[bx].clss
    inputNum stus[bx].id
    inputFloat stus[bx].score
    mov ax, word ptr stus[bx].score
    add sum, ax
    add bx,stuSize
    loop readStu
;==================Menu==============
MENU:
    outputStr EN_MENU
    inputNum op
    cmp op, 0
    jne nxOp
    jmp exit
nxOp:
    cmp op, 2
    je sortById
    cmp op, 3
    je averageScore
    cmp op, 4
    je everyStage
;=====[ sortByScore ]============
sortByScore:
    outputStr EN_TH
    mov cmpById, 0
    call sort
    jmp PRESS
;=====[ sortById ]============
sortById:
    outputStr EN_TH
    mov cmpById, 1
    call sort
    jmp PRESS
;====[ averageScore ]============
averageScore:
    outputStr EN_AV
    mov ax, sum
    mov dx, 0
    or n, 0
    jz sishewuru
    div n
    shl dx, 1
    cmp dx, n
    jb sishewuru
    inc ax
sishewuru:
    getAns ax
    call outputAns
    jmp PRESS
;====[ everyStage ]==============
everyStage:
    outputStr EN_ST
    stage
PRESS:
    outputStr EN_PRS
    PressAny
    clr
    jmp MENU
exit:
    mov ax, 4c00h
    int 21h

;=============outputNumPro==============
; output a decimal number from ax
outputNumPro proc near
    saveReg
    mov bx, bufptr
    or ax, ax
    jnz outLoop
    dec bx
    mov byte ptr [bx], '0'
    jz show
outLoop:
    or ax, ax
    jz show

    mov dx, 0
    mov cx, 10
    div cx
    add dx, '0'
    dec bx 
    mov byte ptr [bx], dl

    jmp outLoop
show:
    mov dx, bx
    mov ah, 9
    int 21h
    recoverReg
    ret
outputNumPro endp
;===================outputAns==============
outputAns proc near
    outputNum ans
    or ans2, 0
    je ansEnd
    outputChar DOT
    outputNum ans2
ansEnd:
    endl
    ret
outputAns endp

;==================outputFun====================
; output
output proc near
    push ax
    push bx
    push cx
    mov bx, 0
    mov cx, n
for:
    outputStr stus[bx].nm
    outputChar BLK
    outputStr stus[bx].clss
    outputChar BLK
    outputNum stus[bx].id
    outputChar BLK
    mov ax, word ptr stus[bx].score
    getAns ax
    call outputAns
    add bx, stuSize
    loop for
return:
    pop cx
    pop bx
    pop ax
    ret
output endp
;===========Sort===============
;sort
sort proc near
    saveReg
    mov dx, 1
for1:
    cmp dx, n
    jne ctn
    jmp done ;jmp can jump far
ctn:
    mov cx, 1
    mov ax, n
    sub ax, dx; n-1..1
    mov bx, 0
    push dx
    mov dx, 0
for2:
    cmp dx, ax
    jne ctn2
    jmp next
ctn2:
    push ax
    or cmpById, 0
    jz sSco
    jmp sId
sSco:
    mov ax, word ptr stus[bx].score
    cmp ax, word ptr stus[bx+stuSize].score
    jmp by
sId:
    mov ax, word ptr stus[bx].id
    cmp ax, word ptr stus[bx+stuSize].id
by:
    pop ax
    jbe nex2
    swap stus[bx], stus[bx+stuSize]
    mov cx, 0
nex2:
    inc dx
    add bx, stuSize
    jmp for2
next:
    pop dx
    inc dx
    cmp cx, 1
    je done
    jmp for1
done:
    call output
    recoverReg
    ret
sort endp


;=============inputFloatPro==============
; input xx.x or xx
; cx <- xx.x * 10
inputFloatPro proc near
    push dx
    push bx
    push ax
    readNonDigit
    mov bx, 0
    mov cx, 0
whileDigit:
    cmp al, '0'
    jb middle ;<0
    cmp al, '9'
    ja middle ;>9
    mov bx, 1
    mul10 cx; cx=cx*10
    jo inFEnd
    toDigit
    add cx, ax; cx+=ax
    jo inFEnd
diNext:
    echoIn
    jmp whileDigit
middle:
    mul10 cx; cx=cx*10
    jo inFEnd
    cmp bx, 1
    jne inFEnd
    cmp al, '.'
    jne inFEnd
lastdigit:
    echoIn
    cmp al, '0'
    jb inFEnd ;<0
    cmp al, '9'
    ja inFEnd ;>9
    toDigit
    add cx, ax; cx+=ax
over:
    echoIn
    cmp al, CR
    je inFEnd
    cmp al, BLK
    je inFEnd
    jmp over
inFEnd:
    pop ax
    pop bx
    pop dx
    ret
inputFloatPro endp


;=============inputNumPro==============
; input a decimal num to [cx]
inputNumPro proc near
    push ax
    push bx
    readNonDigit
    mov cx, 0
inDecLoop:
    cmp al, '0'
    jb inEnd ;<0
    cmp al, '9'
    ja inEnd ;>9
    mul10 cx; cx=cx*10
    jo inEnd
    toDigit
    add cx, ax; cx+=ax
    jo inEnd
inNext:
    echoIn
    jmp inDecLoop
inEnd:
    pop bx
    pop ax
    ret
inputNumPro endp

;=================inStr==================
; input string ends with '\n' or ' ' to [bx]
inStr proc near
    push ax
inStrLoop:
    echoIn
    cmp al, CR
    je inStrEnd
    cmp al, BLK
    je inStrEnd
    mov byte ptr [bx],al
    inc bx
    jmp inStrLoop
inStrEnd:
    mov byte ptr [bx],'$'
    pop ax
    ret
inStr endp
end start

(实验)可编程并行接口8255 方式0

code segment
    assume cs:code
start:
    mov dx, 28bh
    mov al, 10001001b 
    out dx, al
inout: 
    mov dx, 28ah  ;从C口输入数据
    in al, dx
    mov dx, 288h  ;从A口输出
    out dx, al
    mov ah,01h
    int 16h
    jz inout       ;循环
    mov ax, 4c00h
    int 21h
code ends
end start

串口通讯8251

.model small
.data
    msg db 'You can play a key on the keyboard~',0ah,0dh,'$'
    control_port8254 EQU 283h
    data0_port8254 EQU 280h
    control_port8251 EQU 2b9h
    data_port8251 EQU 2b8h
.code
    assume cs:@code,ds:@data
start:
    mov ax,@data
    mov ds,ax
    
    mov dx,control_port8254 ;8254初始化
    mov al,00010110b        ;8254 计数器0工作在方式3
    out dx,al

    mov dx,data0_port8254   ;将初值写入计数器0
    mov al,52
    out dx,al

    mov dx,control_port8251 ;8251初始化
    mov al,01000000b        ;复位命令字
    out dx,al
    nop             ;延时
    mov al,01001110b        ;方式控制字(异步方式,字长8,无校验,波特率因子16)
    out dx,al
    mov al,00100111b        ;工作命令字(RTS,ER,RXE,DTR,TXEN置1)
    out dx,al
    
    lea dx,msg          ;提示信息
    mov ah,09h
    int 21h
    
for1:   mov dx,control_port8251 ;TxRDY为1?
    in al,dx
    test al,01h
    jz for1

for2:   mov ah,01           ;读键盘
    int 21h
    cmp al,27           ;是否是ESC
    jz exit
    
    inc al
    mov dx,data_port8251
    out dx,al
    
for3: mov dx,control_port8251   ;DxRDY为1?
    in al,dx
    test al,02h
    jz for3
    
    mov dx,data_port8251    ;从8251数据口接收数据
    in al,dx
    mov dl,al

    mov ah,02           ;显示数据
    int 21h
    jmp for1

exit: mov ax,4c00h      ;返回操作系统
    int 21h
end start

转载于:https://www.cnblogs.com/flipped/p/7766919.html

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值