zoukankan      html  css  js  c++  java
  • 汇编笔记

    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 '
    
    '
    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 '
    ' 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 '
    ' 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
    
  • 相关阅读:
    SQL Server 触发器
    [转]SQL Server 存储过程
    C#-DataView及其用法
    IEnumerable和IEnumerator 详解 And迭代器
    C#多线程学习(六) 互斥对象
    GDI简单的图片处理
    C#委托的介绍(delegate、Action、Func、predicate)
    接口的理解与使用《转》
    Mysql drop、delete和truncate的区别
    如何查看笔记本CPU是几核的?
  • 原文地址:https://www.cnblogs.com/flipped/p/7766919.html
Copyright © 2011-2022 走看看