Post

内存寻址方式

内存寻址

内存寻址方式
目录

内存寻址

可用于内存寻址的寄存器有且仅有:
bx、bp、si、di
即、仅有上述寄存器可放在 [] 中

注意事项:
指令混合使用的注意点

bx、bp的使用和区别:

  • bx 默认使用 ds段
  • bp 默认使用 ss段
  • 也可显示指定段的方式 更改段地址

处理字符

大小写转换

A: 65 41H 0100 0001
a: 97 61H 0110 0001
大小写之间相差 32,即 2H, 在2进制中,有一位不同

则, 大写转小写:
0100 0001
0010 0000 or
0110 0001

小写转大写:
0110 0001
1101 1111 and
0100 0001

寻址

形式名称特点意义示例
[idata]直接寻址用一个常量/立即数来表示地址用于直接定位一个内存单元mov ax,[200]
[bx]寄存器间接寻址用一个变量来表示内存地址用于间接定位一个内存单元mov bx,0 mov ax,[bx]
[bx+idata]寄存器相对寻址用一个变量和常量表示地址可在一个起始地址的基础上用变量间接定位一个内存单元mov bx, 4 mov ax,[bx+200]
[bx+si]基址变址寻址用两个变量表示地址 mov ax,[bx+si]
[bx+si+idata]相对基址变址寻址用两个变量和一个常量表示地址 mov ax,[bx+si+200]

不同的内存寻址方式:

寻址方式含义名称常用格式举例
[idata]EA=idata;SA=(ds)直接寻址[idata]
[bx]EA=(bx);SA=(ds)  
[si]EA=(si);SA=(ds)寄存器间接寻址[bx]
[di]EA=(di);SA=(ds)  
[bp]EA=(bp);SA=(ss)  
[bx+idata]EA=(bx)+idata;SA=(ds) 用于结构体:[bx].idata
[si+idata]EA=(si)+idata;SA=(ds)寄存器相对寻址用于数组:idata[si],idata[di]
[di+idata]EA=(di)+idata;SA=(ds)  
[bp+idata]EA=(bp)+idata;SA=(ss) 用于二维数组:[bx][idata]
[bx+si]EA=(bx)+(si);SA=(ds)  
[bx+di]EA=(bx)+(di);SA=(ds) 用于二维数组:[bx][si]
[bp+si]EA=(bp)+(si);SA=(ss)基址变址寻址 
[bp+di]EA=(bp)+(di);SA=(ss)  
[bx+si+idata]EA=(bx)+(si)+idata; SA=(ds) 用于表格(结构)中的数组项: [bx].idata[si]
[bx+di+idata]EA=(bx)+(di)+idata; SA=(ds)相对基址变址用于二维数组:
[bp+si+idata]EA=(bp)+(si)+idata; SA=(ss)寻址idata[bx][si]
[bp+di+idata]EA=(bp)+(di)+idata; SA=(ss)  

[bx + idata] 方式寻址

mov ax,[bx+200]
含义:

  1. 将一个内存单元的内容 传输给 ax
  2. 内存单元的长度为 2字节(字单元)
  3. 段地址在ds中
  4. 数学化的描述: (ax)=((ds) * 16 + 200 + (bx))

其它写法:

  1. mov ax, [200+bx]
  2. mov ax, 200[bx]
  3. mov ax, [bx].200

si 和 di 变址寄存器

作为 源操作单元 和 目标操作单元 使用

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
    db 'hello world!'
    db '............'
datasg ends
codesg segment
start:  mov ax,datasg
        mov ds,ax

        mov si,0
        mov di,12
        mov cx,6
    s:  mov ax,[si]
        mov [di],ax
        add di,2
        add si,2
        loop s
        mov ax,4c00h
        int 21h

codesg ends
end start
[bx + si] 和 [bx + di]方式 指定地址

本身 表示一个内存单元

指令 mov ax, [bx+si]含义

  1. 存入一个内存单元的内容 到 ax
  2. 内存单元大小为 2字节 (字单元)
  3. 偏移地址为 bx 和 si 中的数值相加

其它写法:
mov ax,[bx][si]

[bx + si + idata] 和 [bx + di + idata]方式 指定地址

含义、指令含义 同上

指令mov ax, [bx+si+idata]的其它写法:
mov ax,[bx+200+si]

  1. mov ax,200[bx][si]
  2. mov ax,[bx].200[si]
  3. mov ax,[bx][si].200

多重循环的寻址方式

思路:进入循环时 保存 cx 的值,循环前 恢复 cx 的值

  1. 使用额外的寄存器 — 强烈不推荐
  2. 用固定的内存空间 — 不推荐
  3. 用栈 — 推荐

指令处理数据的长度

  1. 字操作 word
    1. 使用寄存器, ax、bx
    2. 每个寄存器操作长度为 1一个字
  2. 字节操作 byte
    1. 使用寄存器 al、ah、bl、bh等
    2. 操作长度为 1 byte
  3. 指明操作
    1. 无寄存器参与运算的情况
    2. mov word ptr ds:[0],1 字操作
    3. inc byte ptr [bx] 字节操作

imul


有符号数的乘法


mul

存储原理:被乘数(8位) $\times$ 乘数(8位) = 积(16位)
格式:

  • 默认被乘数 8位:al, 16位:ax
  • 寄存器乘数
    • 8位乘数 mul bl
    • 16位乘数mul bx
  • 内存单元地址乘数
    • 16位乘数 div word ptr [0]
    • 8位乘数 div byte ptr [0]
 8位乘法16位乘法
被乘数ALAX
乘数8位内存或寄存器16位内存或寄存器
AXDX(high) + AX(low)

idiv


有符号数的除法


div

存储原理:被除数(16位) $\div$ 除数(8位) = 商(8位)
格式:

  • 默认被除数 16位 (对应8位除数):ax, 32位 (对应16位除数):dx + ax
  • 寄存器除数
    • 8位除数 div bl
    • 16位除数div bx
  • 内存单元地址除数
    • 16位除数 div word ptr [0]
    • 8位除数 div byte ptr [0]
被除数AXDX和AX
除数8位内存或寄存器16位内存或寄存器
ALAX
余数AHDX
  • 被除数16位 ax — 除数8位 bl 或 byte ptr
    • 商 al 余 ah
  • 被除数32位 dx+ax — 除数 bx 或
    • 商 ax 余 dx
    • 被除数 dx 存高位、ax存低位

示例:

示例指令被除数除数余数
div bl(ax)(bl)(al)(ah)
div byte ptr ds:[0](ax)((ds)*16+0)(al)(ah)
div byte ptr [bx+si+8](ax)((ds)*16+(bx)+(si)+8)(al)(ah)
div bx(dx)*10000H+(ax)(bx)(ax)(dx)
div word ptr es:[0](dx)*10000H+(ax)(es)*16+0(ax)(dx)
div word ptr [bx+si+8](dx)*10000H+(ax)(es)*16+(bx)+(si)+8(ax)(dx)

dup 重复数据设置内存

作用: 进行内存数据的批量设置

指令功能相当于
db 3 dup(0)定义了3个字节,它们的值都是0db 0,0,0
db 3 dup(0,1,2)定义了9个字节,由0、1、2重复3次构成db 0,1,2,0,1,2,0,1,2
db 3 dup(‘abc’,’ABC’)定义了18个字节,构成’abcABCabcABCabcABC’db ‘abcABCabcABCabcABC’

dup的使用格式

  • db 重复的次数 dup (重复的字节型数据)
  • dw 重复的次数 dup (重复的字型数据)
  • dd 重复的次数 dup (重复的双字数

其它指令和注意事项

数据段存储

DS 与 CS 的隔了 10H程序段前缀
例如: DS=075A, 数据则存放在076A:0, 即076A0H中
前面的100H中存放PSP(Program Segment Prefix, 即程序段前缀),是一个存储在内存中特定位置的数据结构,DOS 操作系统会在每次加载并执行一个程序时为其分配这个前缀区域。

PSP的介绍

PSP 结构和内存布局:

PSP 是 DOS 为每个加载的可执行程序(如 .COM 文件)创建的数据结构,大小正好是 100H 字节。在这个区域存放了程序执行的控制信息,例如传递给程序的命令行参数,环境变量,文件句柄等等。 因此,当程序被加载时,实际上程序代码从 PSP 之后的 100H 开始。这是一个普遍的规则

字符串存入

1
2
3
4
5
assume cs:codesg, ds:datasg
datasg segment
    db 'BaSiC'
    db 'MinIx'
datasg ends
This post is licensed under CC BY 4.0 by the author.