汇编(四)

多段编程

  • 不分段时 [Debug查看]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    assume cs:code

    code segment
    ;define word 的缩写
    dw 0123H,0456H,0789H,0abcH,0defH,0fedH,0cbaH,0987H
    start:mov bx,0
    mov ax,0
    mov cx,8
    s: add ax,cs:[bx] ;由于定义到cs段里面所以,内存的基地址位cs的地址
    add bx,2
    loop s

    mov ax,4c00H
    int 21H
    code ends
    end start ;指定指令入口
  • 分段处理

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    assume cs:code,ds:data,ss:stack

    data segment
    dw 0123H,0456H,0789H,0abcH,0defH,0fedH,0cbaH,0987H
    data ends

    stack segment
    dw 0,0,0,0,0,0,0,0
    stack ends

    code segment

    start: mov ax,stack ;使用段名进行关联
    mov ss,ax
    mov sp,16
    mov ax,data
    mov ds,ax
    push ds:[0]
    push ds:[2]
    pop ds:[2]
    pop ds:[0]

    mov ax,4c00H
    int 21H
    code ends
    end start

灵活定位内存地址

  • [bx+idata] 的方式,也可以写成[idata+bx]idata[bx][bx].idata
  • SI和DI寄存器:类似通用寄存器bx的用法,但是不能想bl和bh那么使用
  • [bx+si]

使用栈存储临时值得案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
assume cs:codesg,ds:datasg,ss:stacksg

datasg segment
db 'ibm '
db 'dec '
db 'dos '
db 'vax '
datasg ends

stacksg segment
dw 0,0,0,0,0,0,0,0
stacksg ends

codesg segment
start: mov ax,stacksg
mov ss,ax
mov sp,16

mov ax,datasg
mov ds,ax

mov bx,0

mov cx,4
s0: push cx ;将外层循环的cx值压栈,防止内循环造成cx错乱
mov si,0
mov cx,3
s: mov al,[bx+si]
and al,11011111b
mov [bx+si],al
inc si
loop s

add bx,16
pop cx ;从栈弹出保存的临时数据存入cx中
loop s0

mov ax,4c00h
int 21h

codesg ends
end start

内存定位相关寄存器的使用

  • bp默认的段寄存器时ss而不是ds
  • bx/bp/si/di 可以单独使用或者以四种组合使用
    bx和si bx和di bp和si bp和di

指定内存单元的长度

  • 使用寄存器执行
  • 内有寄存器参与的内存单元访问使用 word ptrbyte ptr显示的指明所要访问的内存单元的长度
    1
    mov word ptr ds:[0],2
  • 指令自己指定,例如push操作只能进行字操作不进行字节型数据操作

div 除法

  • div byte ptr ds:[0]

    (al) = (ax)/((ds)*16+0)的商
    (ah) = (ax)/((ds)*16+0)的余数

  • div word ptr ds:[0]

    (ax) = [(dx)*10000H+(ax)]/((ds)*16+0)的商
    (dx) = [(dx)*10000H+(ax)]/((ds)*16+0)的余数

  • 100001/100 使用汇编实现

    1
    2
    3
    4
    mov dx,1
    mov ax,86A1H
    mov bx,100
    div bx

    由于100001大于65535所以需要使用两个寄存器存储 ax存低8位 dx存高8位,虽然除数100小于255但是被除数使用的32位的所以除数只能使用16位寄存器存储而不能使用字节存储

  • 用数据段中第一个数除以第二个数将商放到第三个数据的存储单元中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    assume cs:codesg,ds:datasg

    datasg segment
    dd 100001
    dw 100
    dw 0
    datasg ends

    codesg segment
    start: mov ax,datasg
    mov ds,ax

    mov ax,ds:[0]
    mov dx,ds:[2]

    div word ptr ds:[4]
    mov ds:[6],ax

    mov ax,4c00h
    int 21h

    codesg ends
    end start

汇编中的数据类型定义

  • db 定义字节类型 8位
  • dw 定义字类型 16位
  • dd 定义双字类型 32位
  • dup 定义重复操作

    db 3 dup (0) 相当于定义了 db 0,0,0
    db 3 dup ‘AA’ 相当于 db ‘AAAAAA’