有长度标号

注意这里是没有:的标号

  1. assume cs:code
  2. code segment
  3. a db 1,2,3,4,5,6,7,8
  4. b dw 0
  5. start: mov si,0
  6. mov cx,8
  7. s: mov al,a[si] ; a[si] 表示 a[0](cs:[0]) 的内容, a 等价
  8. mov ah,0
  9. add b,ax ; b 的地址是 0008, 因此 add b,ax 等价于 add cs:[0008],ax
  10. inc si
  11. loop s
  12. mov ax,4c00h
  13. int 21h
  14. code ends
  15. end start

不同段中使用标号

  1. assume cs:code,ds:data
  2. data segment
  3. a db 1,2,3,4,5,6,7,8
  4. b dw 0
  5. data ends
  6. code segment
  7. start: mov ax,data
  8. mov ds,ax
  9. mov si,0
  10. mov cx,8
  11. s: mov al,a[si] ; a[si] 表示 a[0](cs:[0]) 的内容, a 等价
  12. mov ah,0
  13. add b,ax ; b 的地址是 0008, 因此 add b,ax 等价于 add cs:[0008],ax
  14. inc si
  15. loop s
  16. mov ax,4c00h
  17. int 21h
  18. code ends
  19. end start

存储标号地址

  1. data segment
  2. a db 1,2,3,4,5,6,7,8
  3. b dw 0
  4. c dw a,b ; 相当于 offset a,offset b
  5. data ends
  1. data segment
  2. a db 1,2,3,4,5,6,7,8
  3. b dw 0
  4. c dd a,b ; 相当于 offset a,seg a,offset b,seg b
  5. data ends

seg a得到a的段地址

直接定值表

数值0~F0~FASCII码没有一一对应的关系,因此建立一张表,将位置(数值)和字符建立一一对应的关系

  1. ; 以下程序实现 al=2B 即可在屏幕上显示 2B, al=3B 就显示 3B, 以此类推
  2. assume cs:code
  3. code segment
  4. showbyte: jmp short show
  5. table db '0123456789ABCDEF'
  6. show: push bx
  7. push es
  8. mov ah,al
  9. shr ah,1
  10. shr ah,1
  11. shr ah,1
  12. shr ah,1
  13. and al,00001111b
  14. mov bl,ah
  15. mov bh,0
  16. mov ah,table[bx]
  17. mov bx,0b800h
  18. mov es,bx
  19. mov es:[160*12+40*2],ah ; 显示高位
  20. mov bl,al
  21. mov bh,0
  22. mov al,table[bx]
  23. mov es:[160*12+40*2+2],al ; 显示低位
  24. pop es
  25. pop bx
  26. ret
  27. start: mov ax,002BH ; 16 进制拆成两个 8 进制, 高位 2 和低位 B
  28. call showbyte ; 必须用 call 因为这会将 CS:IP 入栈, 调用 ret 才能正确返回
  29. mov ax,4c00h
  30. int 21h
  31. code ends
  32. end start

程序入口地址直接定址表

  1. 清屏

    1. sub1: push bx
    2. push cx
    3. push es
    4. mov bx,0b800h
    5. mov es,bx
    6. mov bx,0
    7. mov cx,2000
    8. sub1s: mov byte ptr es:[bx],' '
    9. add bx,2
    10. loop sub1s
    11. pop es
    12. pop cx
    13. pop bx
    14. ret
  2. 设置前景色

    1. sub2: push bx
    2. push cx
    3. push es
    4. mov bx,0b800h
    5. mov es,bx
    6. mov bx,1
    7. mov cx,2000
    8. sub2s: and byte ptr es:[bx],11111000b
    9. or es:[bx],al
    10. add bx,2
    11. loop sub2s
    12. pop es
    13. pop cx
    14. pop bx
    15. ret
  3. 设置背景色

    1. sub3: push bx
    2. push cx
    3. push es
    4. mov cl,4
    5. shl al,cl
    6. mov bx,0b800h
    7. mov es,bx
    8. mov bx,1
    9. mov cx,2000
    10. sub3s: and byte ptr es:[bx],10001111b
    11. or es:[bx],al
    12. add bx,2
    13. loop sub3s
    14. pop es
    15. pop cx
    16. pop bx
    17. ret
  4. 向上滚动一行

    1. sub4: push cx
    2. push si
    3. push di
    4. push es
    5. push ds
    6. mov si,0b800h
    7. mov es,si
    8. mov ds,si
    9. mov si,160
    10. mov di,0
    11. cld
    12. mov cx,24
    13. sub4s: push cx
    14. mov cx,160
    15. rep movsb
    16. pop cx
    17. loop sub4s
    18. mov cx,80
    19. mov si,0
    20. sub4s1: mov byte ptr [160*24+si],' '
    21. add si,2
    22. loop sub4s1
    23. pop ds
    24. pop es
    25. pop di
    26. pop si
    27. pop cx
    28. ret
  5. 主程序 ``` assume cs:code

code segment ; 各种子程序 setscreen: jmp short set

  1. table: dw sub1,sub2,sub3,sub4
  2. set: push bx
  3. cmp ah,3
  4. ja sret
  5. mov bl,ah
  6. mov bh,0
  7. add bx,bx
  8. call word ptr table[bx]
  9. sret: pop bx
  10. ret

start: mov ah,1 ; 功能选择 mov al,3 call setscreen

  1. mov ax,4c00h
  2. int 21h

code ends

end start ```