汇编语言学习
学习资料
图书:http://c.biancheng.net/view/3378.html
视频:https://www.bilibili.com/video/BV1mt411R7Xv?from=search&seid=7216001317872532936
思维导图:https://pan.baidu.com/s/1HAGT3w0dszhZhJf_a_ccHg 提取码:9pmu XMind打开方式?
习题答案: https://blog.csdn.net/heiyeleng/article/details/50651602
延伸阅读:与程序员相关的CPU缓存知识
汇编程序
- 
改变屏幕颜色
7 6 5 4 3 2 1 0
BL R G B I R G B
闪烁 背景 高亮 前景
 
assume cs:code,ds:data,ss:stack
data segment
    db 128 dup (0)
data ends
stack segment stack
    db 128 dup (0)
stack ends
code segment
    start:
        mov ax,stack
        mov ss,ax
        mov sp,128
        call init_reg
        call set_screen
        mov ax,4C00H
        int 21H
;=======================
    set_screen:
        mov bx,1
        mov cx,2000
        mov dl,00000101B
    do:
        mov es:[bx],dl
        add bx,2
        loop do
    ret
;========================
    init_reg:
        mov bx,0B800H
        mov es,bx
        mov bx,data
        mov ds,bx
    ret
code ends
end start
2.屏幕特定位置打印语句
assume cs:code,ds:data,ss:stack
data segment
    db 'welcome to masm!'
    db 'welcome to masm!'
    db 'welcome to masm!'
    db 'welcome to masm!'
data ends
stack segment stack
    db 128 dup (0)
stack ends
code segment
    start:
        mov ax,stack
        mov ss,ax
        mov sp,128
        mov ax,data
        mov ds,ax
        mov bx,0
        mov si,0
        mov cx,4
    outer:
        push cx
        push si
        mov cx,16
    inner:
        and byte ptr ds:[bx+si],11011111B
        inc si
        loop inner
        add bx,16
        pop si
        pop cx
        loop outer
        mov ax,4C00H
        int 21H
code ends
end start
3.寻址方式在结构化数据访问中的应用
assume cs:code,ds:data,ss:stack
;将数据制表
data segment
    ;years
    db      '1975','1976','1977','1978','1979','1980','1981'
    db      '1982','1983','1984','1985','1986','1987','1988'
    db      '1989','1990','1991','1992','1993','1994','1995'
    ;income
    dd       16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
    dd       345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
    ;staff
    dw      3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037
    dw      5635,8226,11542,14430,15257,17800
data ends
table segment
                ;0123456789ABCDEF
    db  21 dup ('year summ ne ?? ')
table ends
stack segment stack
    db  128 dup (0)
stack ends
code segment
    start:
        mov ax,stack
        mov ss,ax
        mov sp,128
        mov ax,data
        mov ds,ax
        mov ax,table
        mov es,ax
        mov bx,0
        mov di,21*4+21*4
        mov bp,0
        mov cx,21
    do:
        ;year
        push ds:[bx]
        pop es:[bp]
        push ds:[bx+2]
        pop es:[bp+2]
        ;summ
        push ds:[bx+21*4]
        pop es:[bp+5]
        push ds:[bx+21*4+2]
        pop es:[bp+7]
        ;ne
        push ds:[di]
        pop es:[bp+10]
        ;??
        mov dx,es:[bp+7]
        mov ax,es:[bp+5]
        div word ptr es:[bp+10]
        mov es:[bp+13],ax
        add bx,4
        add di,2
        add bp,16
        loop do
        mov ax,4C00H
        int 21H
code ends
end start
4.将内存字符显示到屏幕
assume cs:code,ds:data,ss:stack
data segment
    db 'welcome to masm!'
    db 10000010B,00101100B,01110001B
data ends
stack segment stack
    db  128 dup (0)
stack ends
code segment
    start:
        mov ax,stack
        mov ss,ax
        mov sp,128
        call init_reg
        call clear_screen
        call show_string
        mov ax,4C00H
        int 21H
;=======================
show_string:
        mov bx,0
        mov si,16
        mov bp,160*11+72
        mov cx,3
    outer:
        push cx
        push bx
        push bp
        mov dh,ds:[si]
        mov cx,16
    inner:
        mov dl,ds:[bx]
        mov es:[bp],dx
        inc bx
        add bp,2
        loop inner
        pop bp
        pop bx
        pop cx
        inc si
        add bp,160
        loop outer
    ret
;=======================
clear_screen:
        mov bx,0
        mov dx,0
        mov cx,2000
    do:
        mov es:[bx],dx
        add bx,2
        loop do
    ret
;=======================
init_reg:
        mov ax,data
        mov ds,ax
        mov ax,0B800H
        mov es,ax
    ret
;========================
code ends
end start
5.转移指令的应用
assume cs:code,ds:data,ss:stack
data segment
    db  '1) restart pc',0
    db  '2) start system',0
    db  '3) show clock',0
    db  '4) set clock',0
data ends
stack segment stack
    db  128 dup (0)
stack ends
code segment
    start:
        mov ax,stack
        mov ss,ax
        mov sp,128
        call init_reg
        call clear_screen
        mov bx,0
        mov si,16
        mov bp,160*11+72
        call show_string
        mov ax,4C00H
        int 21H
;=======================
show_string:
        mov cx,4
        mov dh,00000100B
    outer:
        push cx
        push bp
        mov ch,0
    inner:
        mov cl,ds:[bx]
        jcxz ok
        mov es:[bp],cl
        inc bp
        mov es:[bp],dh
        inc bx
        inc bp
        jmp inner
    ok:
        pop bp
        pop cx
        inc bx
        add bp,160
        loop outer
    ret
;=======================
clear_screen:
        mov bx,0
        mov dx,0
        mov cx,2000
    do:
        mov es:[bx],dx
        add bx,2
        loop do
    ret
;=======================
init_reg:
        mov ax,data
        mov ds,ax
        mov ax,0B800H
        mov es,ax
    ret
;========================
code ends
end start
6.课程设计一,数据处理
assume cs:code,ds:data,ss:stack
;将数据制表
data segment
    ;years
    db      '1975','1976','1977','1978','1979','1980','1981'
    db      '1982','1983','1984','1985','1986','1987','1988'
    db      '1989','1990','1991','1992','1993','1994','1995'
    ;income
    dd       16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
    dd       345980,590827,80353,118300,184300,275900,375300,464900,593700
    ;staff
    dw      3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037
    dw      5635,8226,11542,14430,15257,17800
data ends
table segment
                ;0123456789ABCDEF
    db  21 dup ('year summ ne ?? ')
table ends
stack segment stack
    db  128 dup (0)
stack ends
code segment
    start:
;stack
        mov ax,stack
        mov ss,ax
        mov sp,128
;src
        mov ax,data
        mov ds,ax
        mov bx,0
;desc
        mov ax,table
        mov es,ax
        mov bp,0
        call to_table
        call clear_screen
;src
        mov ax,table
        mov ds,ax
        mov bx,0
;desc
        mov ax,0B800H
        mov es,ax
        mov bp,160*2+10
        call to_screen
        mov ax,4C00H
        int 21H
;========================
to_screen:
    mov byte ptr ds:[21*4*3],4
    mov cx,21
do_to_screen:
    call show_year
    call show_summ
    call show_ne
    call show_avg
    add bx,16
    add bp,160
    loop do_to_screen
    ret
;========================
to_number_show_screen:
    push cx
    mov si,10
div_si:
    div si
    mov cx,ax
    add dl,30H
    mov dh,ds:[21*4*3]
    mov es:[bp],dx
    jcxz break_div
    mov dx,0
    sub bp,2
    jmp div_si
break_div:
    pop cx
    ret
;========================
show_avg:
    mov dx,0
    mov ax,ds:[bx+13]
    push bp
    add bp,60
    call to_number_show_screen
    pop bp
    ret
;========================
show_ne:
    mov dx,0
    mov ax,ds:[bx+10]
    push bp
    add bp,50
    call to_number_show_screen
    pop bp
    ret
;========================
show_summ:
    mov dx,ds:[bx+7]
    mov ax,ds:[bx+5]
    push bp
    add bp,30
    call to_number_show_screen
    pop bp
    ret
;========================
show_year:
    push cx
    push bp
    push bx
    mov cx,4
    mov dh,ds:[21*4*3]
do_year:
    mov dl,ds:[bx]
    mov es:[bp],dx
    inc bx
    add bp,2
    loop do_year
    pop bx
    pop bp
    pop cx
    ret
;========================
clear_screen:
        mov bx,0B800H
        mov es,bx
        mov bx,0
        mov dx,0
        mov cx,2000
    do_screen:
        mov es:[bx],dx
        add bx,2
        loop do_screen
    ret
;========================
to_table:
        mov di,21*4+21*4
        mov cx,21
    do_table:
        ;year
        push ds:[bx]
        pop es:[bp]
        push ds:[bx+2]
        pop es:[bp+2]
        ;summ
        push ds:[bx+21*4]
        pop es:[bp+5]
        push ds:[bx+21*4+2]
        pop es:[bp+7]
        ;ne
        push ds:[di]
        pop es:[bp+10]
        ;??
        mov dx,es:[bp+7]
        mov ax,es:[bp+5]
        div word ptr es:[bp+10]
        mov es:[bp+13],ax
        add bx,4
        add di,2
        add bp,16
        loop do_table
    ret
code ends
end start
7.代码复制
assume cs:code,ds:data,ss:stack
data segment
    db 128 dup (0)
data ends
stack segment stack
    db 128 dup (0)
stack ends
code segment
start:
    mov ax,stack
    mov ss,ax
    mov sp,128
    call copy_code
    mov ax,4C00H
    int 21H
;===================
boot:
    mov ax,4C00H
    int 21H
boot_end: nop
;===================
copy_code:
    mov bx,cs
    mov ds,bx
    mov si,OFFSET boot   ;ds:[si]
    mov bx,0
    mov es,bx
    mov di,7E00H         ;es:[di]
    mov cx,OFFSET boot_end - OFFSET boot
    cld
    rep movsb
ret
code ends
end start
8.课程设计2
assume cs:code,ds:data,ss:stack
stack segment
 db 128 dup (0)
stack ends
data segment
 begin        db 512 dup (0)
 begin_boot   db 512 dup (0)
              db 512 dup (0)
              db 512 dup (0)
data ends
code segment
start: 
       mov ax,stack
       mov ss,ax
       mov sp,128
       
       call copy_introduce
       call copy_boot_disk
       mov ax,4c00h
       int 21h
;===============================
introduce:                     ;引导程序,将程序复制到0:7c00处,
        mov bx,0
    mov ss,bx
    mov sp,7c00h
    call save_old_int9
    call copy_Boot_fromdisk
    mov bx,0
    push bx
    mov bx,7e00h           ;设置cs:ip为0:7e00h执行Boot程序
    push bx
    retf
;===============================
copy_Boot_fromdisk:
        mov bx,0
    mov es,bx
    mov bx,7e00h
    mov al,2
    mov ch,0
    mov cl,2
    mov dl,0
    mov dh,0
    mov ah,2
    int 13h
    ret
;===============================
 save_old_int9:
       mov bx,0
       mov es,bx
       push es:[9*4]
       pop es:[200h]
       push es:[9*4+2]
       pop es:[202h]
       ret
;===============================
       db 512 dup (0)
introduce_end:nop
;=================================
copy_introduce:
       mov bx,cs
       mov es,bx
       mov bx,offset introduce
       mov al,1
       mov ch,0
       mov cl,1
       mov dl,0
       mov dh,0
       mov ah,3
       int 13h
       ret
;===============================
copy_boot_disk:
       mov bx,cs
       mov es,bx
       mov bx,offset Boot
       mov al,2
       mov ch,0
       mov cl,2
       mov dl,0
       mov dh,0
       mov ah,3
       int 13h
       ret
;===============================
Boot:
       jmp Boot_start
;===============================
option1   db '(1) reset pc',0
option2   db '(2) start system',0
option3   db '(3) clock',0
option4   db '(4) set clock',0
address_option   dw offset option1 - offset Boot + 7e00h
                 dw offset option2 - offset Boot + 7e00h
                 dw offset option3 - offset Boot + 7e00h
                 dw offset option4 - offset Boot + 7e00h
 timestyle   db '00/00/00 00:00:00',0
 timeadress  db 9,8,7,4,2,0
 string_stack   db 12 dup ('0'),0
;===============================    
Boot_start:
        call init_reg
    call clear_screen
    call show_option
    jmp short choose_option
        
    mov ax,4c00h
        int 21h
;===============================
choose_option:
        call clear_buff
        
    mov ah,0
    int 16h
    cmp al,'1'
    je choose1
    cmp al,'2'
    je choose2
    cmp al,'3'
    je choose3
    cmp al,'4'
    je choose4
        jmp choose_option
choose1:mov di,160*3
        mov byte ptr es:[di],'1'
    mov bx,0ffffh
    push bx
    mov bx,0
    push bx
    retf
        jmp choose_option
choose2:mov di,160*3
        mov byte ptr es:[di],'2'
    call start_old_system
        jmp choose_option
choose3:mov di,160*3
        mov byte ptr es:[di],'3'
    call show_clock
        jmp Boot_start
choose4:mov di,160*3
        mov byte ptr es:[di],'4'
    call set_clock
        jmp choose_option
;===============================
start_old_system:
        mov bx,0
    mov es,bx
    mov bx,7c00h
    mov al,1
    mov ch,0
    mov cl,1
    mov dl,80h     ;80h代表C盘
    mov dh,0
    mov ah,2
    int 13h
        mov bx,0
    push bx
    mov bx,7c00h
    push bx
    retf
;===============================
set_clock:
        call clear_string_stack
        call show_string_stack
    call get_string
    call set_time
    ret
;===============================
set_time:
        mov bx,offset timeadress - offset Boot + 7e00h
    mov si,offset string_stack - offset Boot +7e00h
    mov cx,6
settime:
        mov dx,ds:[si]
    sub dh,30h
    sub dl,30h
    shl dl,1
    shl dl,1
    shl dl,1
    shl dl,1
    and dh,00001111b
    or dl,dh
    mov al,ds:[bx]
    out 70h,al
    mov al,dl
    out 71h,al
        add si,2
    inc bx
    loop settime
        ret
;===============================
get_string:
        mov si,offset string_stack - offset Boot + 7e00h
    mov bx,0
getstring:
        call clear_buff
    mov ah,0
    int 16h
    cmp al,'0'
    jb notnumber
    cmp al,'9'
    ja notnumber
    call char_push
    call show_string_stack
    jmp getstring
getstringret:
        ret
notnumber:
        cmp ah,0eh
    je isbackspace
    cmp ah,1ch
    je getstringret
    jmp getstring
isbackspace:
        call char_pop
    call show_string_stack
        jmp getstring
;===============================
char_pop:
        cmp bx,0
    je charpopret
    dec bx
    mov byte ptr ds:[si+bx],'0'
charpopret:
        ret
;===============================
char_push:
        cmp bx,11
    ja charpushret
    mov ds:[si+bx],al
    inc bx
charpushret:
        ret
;===============================
show_string_stack:
        push si
    push di
    mov si,offset string_stack - offset Boot + 7e00h
        mov di,160*4
    call showstr
    pop di
    pop si
    ret
;===============================
clear_string_stack:
        push bx
    push cx
    push es
    push si
    push di
        mov si,offset string_stack - offset Boot + 7e00h
    mov dx,3030h
    mov cx,6
clearstringstack:
        mov ds:[si],dx
    add si,2
    loop clearstringstack
    pop di
    pop si
    pop es
    pop cx
    pop bx
    ret
;===============================
show_clock:
        call show_style
    call set_new_int9
        
    mov bx,offset timeadress - offset Boot + 7e00h
 showtime:       
    mov si,bx
    mov di,160*20
    mov cx,6
showdate:
        mov al,ds:[si]
    out 70h,al
    in al,71h
    mov ah,al
    shr ah,1
    shr ah,1
    shr ah,1
    shr ah,1
    and al,00001111b
    add ah,30h
    add al,30h
    mov es:[di],ah
    mov es:[di+2],al
    add di,6
    inc si
    loop showdate
        jmp showtime
show_clockret:
       call set_old_int9
       ret
;===============================
show_style:
       mov si,offset timestyle - offset Boot + 7e00h
       mov di,160*20
       call showstr
       ret
;===============================
set_old_int9:
       push bx
       push es
       mov bx,0
       mov es,bx
       cli
       push es:[200h]
       pop es:[9*4]
       push es:[202h]
       pop es:[9*4+2]
       sti
       pop es
       pop bx
       ret
;===============================
set_new_int9:
       push bx
       push es
       mov bx,0
       mov es,bx
       cli
       mov word ptr es:[9*4],offset newint9 - offset Boot + 7e00h
       mov word ptr es:[9*4+2],0
       sti
       
       pop es
       pop bx
       ret
;===============================
newint9:
       push ax
       call clear_buff
       in al,60h
       pushf
       call dword ptr cs:[200h]
       
       cmp al,01h
       je inesc
       cmp al,3bh
       jne int9ret
       call change_time_color
       
int9ret:
       pop ax
       iret
inesc:
       pop ax
       add sp,4
       popf
       jmp show_clockret
;===============================
change_time_color:
       push bx
       push cx
       push es
       mov bx,0b800h
       mov es,bx
       mov cx,17
       mov bx,160*20+1
change_time_colors:
       inc byte ptr es:[bx]
       add bx,2
       loop change_time_colors
       pop es
       pop cx
       pop bx     
;===============================
clear_buff:
        mov ah,1
    int 16h
    jz clearbuffret
    mov ah,0
    int 16h
    jmp clear_buff
clearbuffret:
    ret
;===============================
show_option:
        mov bx,offset address_option - offset Boot + 7e00h
        mov cx,4
    mov di,160*10 + 30*2
show_options:
        mov si,ds:[bx]
    call showstr
    add di,160
    add bx,2
    loop show_options
    ret
;===============================
showstr:
        push cx  
    push di
showstrs:
    mov cl,ds:[si]
        cmp cl,0
    je showstrret
    mov es:[di],cl
    add di,2
    inc si
    jmp short showstrs
showstrret:
        pop di
        pop cx
    ret
;===============================
init_reg:
       mov bx,0b800h
       mov es,bx
       mov bx,0
       mov ds,bx
       ret
;===============================
clear_screen:
       mov bx,0
       mov dx,0700h   ;清屏中对字符属性设置应该为07h,而不是0
       mov cx,2000
clearscreen:
       mov es:[bx],dx
       add bx,2
       loop clearscreen
       ret
;===============================
       db 512 dup (0)
Boot_end:
       nop
           
code ends
end start

                
            
        
浙公网安备 33010602011771号