按照自己的思维,把寻址分为 [ ] 的有无,提出 []寻址。
主要是感觉书中的寻址方法繁琐,所以自己归纳,仅作参考。
关于寻址我分为 关于段寄存器的 与 不关于段寄存器的
不关与段寄存器DS与SS的寻址
1、直接将数据送入寄存器中
mov ax,1234h
mov ax,34h --> 34H是根据目的寄存器而改变,ax为十六位,所以为 0034H,是16位
mov al,34H --> al是8位寄存器,所以为 34H,是8位
2、寄存器与寄存器之间送数据
mov ax,bx ; 十六位和十六位
mov al,bh ; 八位和八位
;送数据、装数据,外面一般用AX,BX,CX,DX通用寄存器。
位数要保存一致
可以这样思考
如果八位送给十六位寄存器,是放在高八位还是第八位
如果十六位寄存器送给八位寄存器,是送高八位还是低八位
凡是有歧义的程序,都是错误的
mov al,1234H --> 错误 al为8位
//===========================================
关于段寄存器DS与SS的寻址
先举个例子实践,再分析原理。
mov ax,[0]
;这条指令的意思就是将 段地址为数据段,偏移地址为0(DS:0)的后 两字节 的数据
;送到 ax寄存器 中
;送的字节数是根据目的寄存器的位数决定,比如ax是送 两 字节,al是送 一 字节
送的字节数是根据目的寄存器的位数决定
分析数据段的内容,画图分析。
例如
DATA SEGMENT
DA1 DW 2437H,14A2H
DA2 DW ‘ABCD’
DA3 DW 10 DUP (?)
DATA ENDS
执行上面这段代码过后,数据段(DS)中的内容为
执行指令 mov ax,[0]
就是将 数据段 偏移地址为 0000 d的后 两字节 数据送入 ax 中
如下图,就是数据段 偏移地址为0000后两字节的数据。
下面为高八位,上面为低八位,高八位在前,低八位在后
简记:下高上低,前高后低
所以执行mov ax,[0] 指令过后, ax = 2437H
上面有些不理解没关系,先实践再分析,下面提出 [ ]寻址 的核心思想。
怎么区分寻址方式,又该怎么写?
先提出一些概念
在关于 []寻址 中,如果没有标示出寄存器,如 [bx]、[bp]等,段寄存器默认只有数据段(DS)或堆栈段(SS)。想要调用其他段寄存器,可以写成 es:100 形式,需要自己标示出段寄存器。
基址寄存器 BX BP B --> base,基础
变址寄存器 SI DI I --> index,变址
[ ]寻址 中非常重要的四个寄存器,必须记牢
**一、[ ] 括号内无寄存器
[ ]括号内无寄存器,那么段寄存器默认是在DS中
mov ax,[4] --> 默认在DS
mov [4],ax
二、[ ]内为单个寄存器
基址或变址寻址
[BP] --> 堆栈段(SS)
[BX]、[SI]、[DI] --> 数据段(DS)
``````c
[ ]内还可以加偏移量,偏移量的写法主要有两种(内加和外加)。
1、[ ]括号里面加偏移量(内加) [BX+5]
2、[ ]括号外面加偏移量(外加) 5[BX]
[BX+5] = 5[BX],两种写法效果相同。
三、[ ]内为两个个寄存器
只能是基址+变址寻址
基址+基址;变址+变址都是错误的
[BP+DI] -->堆栈段(SS)
[BP+SI]、[BX+SI]、[BX+DI] -->数据段(DS)
也可以在内外加偏移量
内加:[BP+SI + 5]
外加:5[BP+SI]
[BP+SI + 5] = 5[BP+SI], 效果也相同
在[ ]寻址中,如果[ ]中还要其他寄存器,那就错
例如 mov ax,[dx] -->错,有其他寄存器
mov ax,[bx+ax] -->错,有其他寄存器
mov ax,[bx+bp] -->错 都是基址寄存器,不搭配
还是用这个例子练习,分析数据的内容:
DATA SEGMENT
DA1 DW 2437H,14A2H
DA2 DW ‘ABCD’
DA3 DW 10 DUP (?)
DATA ENDS
**段寄存器**不能直接用立即数送数据,可以先将立即数送给通用寄存器,
再用通用寄存器送给段寄存器
例将1000送到DS中
mov ds,1000 --> 错误写法
可以改成
mov ax,1000
mov ds,ax
我们也经常用这种方法设置段寄存器的 段基地址
分析下面代码执行的结果
;汇编代码
DATA SEGMENT
DA1 DW 2437H,14A2H
DA2 DW ‘ABCD’
DA3 DW 10 DUP (?)
DATA ENDS
mov ax,05h
mov bx,03h
mov si,02h
mov ax,[4]
mov ax,[ax+1]
mov dx,[bx+si + 1]
mov dx,[bx+si]
mov [bx],ax
根据上面数据段的定义,再来分析下面的指令,分析每条指令的的执行结果和原理。
直接送数据
mov ax,05h -->ax = 05h
mov bx,03h -->bx = 03h
mov si,02h -->si = 02h
mov ax,[4] --> ax = 4241H
找到数据段(DS)中偏移地址为 4 的后两字节送入ax中
mov ax,[ax+1] --> ax = 4443h
[ax+1] = [05h +1] = [06h]
找到DS中偏移地址为 6 的后两字节送入ax中
mov dx,[bx+si + 1] --> dx= 4443h
[bx+si+1] = [03h+02h+1] = [06h];
找到DS中偏移地址为6的后两字节送入dx中
mov dx,[bx+si] --> dx = 4342h
[bx+si+1] = [03h+02h] = [05h];
找到DS中偏移地址为5的后两字节送入dx中
mov [bx],ax -->
因为bx = 0,所以[bx] = [0]
所以将ax的内容送入数据段中偏移地址为bx的后两字节内存中
是数据段中的内容改变
理解上面代码的执行原理,每一步都要了解。
[ ] 表示内存单元,其实也就是对应位置的数据
如果写 mov [bx],[si] -->错误,因为都有[ ],
目的操作数和源操作数都是内存单元,都代表数据
执行指令必须要有寄存器
再说一下寻址的重要性,寻址涉及芯片的寻址方式,大小,意义
方式: 段地址:偏移地址 的方法
大小:0:0 ~ FFFF:FFFF
意义:找到准确的数据进行处理,传送或运算等
判断思维:
1、判断是否有[ ],涉及[ ]就找对应的段寄存器内容进行运算,不涉及就直接运算
2、判断[]中有多少寄存器,根据寄存器的个数进行分析
例如下列指令:
;不涉及 []寻址
mov ax,bx ;ax = bx
mov ax,1245h ;ax = 1245h
add ax,bx ; ax = ax + bx
sub ax,bx ;ax = ax - bx
;这些指令不涉及 [ ]寻址,所以直接运算。
;涉及 []寻址
Mov ax,[bx] ;找到 DS 中偏移地址为bx的后 两字节 送入ax中
Mov dx,5[bp] ;找到 ss 中偏移地址为bp+5的后 两字节 送入dx中
Mov al,[bx+si] ;找到 ds 中偏移地址为bx+si的后 一字节 送入dx中
如果指令涉及数据段(DS)或者堆栈段(SS),需要对DS或SS进行分析,最好是画图分析,比较直观。
汇编寻址原理一定得理解,几乎所有指令就是关于寄存器数据的处理
比如相互赋值,找到数据进行运算等等,准确找到数据是非常重要的一步。
因为汇编就是修改寄存器中的内容去控制 cpu 控制整个计算机