asm:操作数寻址的七种方式(intel8086 - masm.exe)
在汇编汇编语言中,很多命令需要“操作数(参数)”。“操作数”给出的方式,有三类。第一类,“直接”给出操作数;第二类,操作数存储在“寄存器”内;第三类,操作数存储在“内存”内。其中,直接给出操作数,包含一种方法。在“寄存器”中给出操作数,包含一种方法。在“内存”中给出操作数,包含五种方法。由此可见,给出“操作数”,一共包含七种方法。
一、(立即数寻址)立即数寻址方式:
1、 直接给出“操作数”。
1 mov ax, 0000h ; 立即数寻址
2 mov ds, ax
二、(寄存器寻址)寄存器寻址方式:
1、操作数,存储在“寄存器”内。先将操作数存储在“寄存器X”中,然后将“寄存器X”作为命令的操作数。
1 mov ax, 0000h
2 mov ds, ax ; 寄存器寻址
3 mov bx, 0000h
三、(内存寻址)直接寻址方式:
1、直接寻址:直接给出“操作数”在数据段内的偏移地址。内存的绝对地址 = 段地址*16 + 直接寻址。
2、地址总线:假设“地址总线”包含n根线。那么“地址总线”,一次性可以传送n位二进制数。那么“地址总线”,一共可以传递2exp(n)个不同的数据(地址)。那么,“地址总线”一共可以访问内存单元的数量是2exp(n)。那么,“地址总线”的寻址范围为:0~2exp(n)。说明:2exp(n) = 2的n次方。
3、segment(段):segment(段),是CPU中的概念。由于CPU中“寄存器的位数”,限制了输入输出数据的位数。如果CPU输出的数据是“内存地址”,那么“寄存器的位数”就限制了CPU操作内存的范围。当寄存器位数小于地址总线位数的时候;CPU访问内存的地址范围小于地址总线提供内存的范围。为了发挥地址总线的全部能力,需要增加CPU生成地址数据的位数。为了增加CPU地址数据的位数,采用了“拼接”数据的方式。拼接数据的方式:地址数据位数=段地址+偏移地址;段的概念诞生了。内存分段的数量,如何确定?“寄存器位数n”生成n位不同的二进制数据的数量;“寄存器位数n”可以生成2exp(n)个n位不同的二进制数据;那么,内存可以分为2exp(n)个段。由此可知,16位的寄存器,可以产生2exp(16)=65536个n位不同的数据;那么,16位寄存器,可以将内存分成65536个段。现在开始讲解“偏移地址”。寄存器位数n,决定每个段的内存范围。同段寄存器的道理相同。寄存器位数n,可以访问2exp(n)个内存空间。16位的寄存器,可以产生64436个不同的n位数据。即16位的寄存器,可以访问65536个内存单元。由于内存最小的单位是字节(1byte=8bits),那么16位寄存器可以方位的内存空间大小是:65536 x 1 byte = 65536bytes= 65536/1024=64 KB(Kilo Bytes)。即偏移范围是64KB,每个段的大小是64KB。
4、寻址方式【段地址+偏移地址】:
4.1、说明:段是逻辑概念。段,是因为寄存器位数不足以产生与地址总线位数相匹配的地址数据而产生的逻辑概念。
4.2、段:分段数量,由寄存器的最大位数决定。
4.3、段的大小:段的大小,由偏移范围决定,偏移范围由寄存器的位数决定。
4.4、16位寄存器:段的最大数量是2exp(16)=65536个。每个段的内存大小是65536bytes=64KB。16位寄存器可以访问的最大内存:段的数量*段的大小=65536*64KB=4096MB=4GB
4.5、8086地址的拼接方式:内存地址=(16位段地址寄存器)x16 + (16位偏移地址寄存器);内存地址等于,“段地址寄存器”向左移动1位,然后加上,“偏移地址寄存器”。
5、直接寻址,属于【段地址 + 偏移地址】
6、直接寻址:操作数存储在内存中。操作数存储在内存的数据段内。数据段的段地址必须存储在“寄存器DS”内。操作数在数据段内的偏移地址可以直接给出。
7、计算示例中的内存地址:数据段地址DS=1000H,偏移地址:0000H,数据在内存中的绝对地址=DS*16+0000H=10000H。
1 mov ax, 00eeh
2 mov [0000], ax
3 mov ds, [0000] ; 直接寻址
四、(内存地址)寄存器间接寻址方式:
1、寄存器间接寻址:寄存器间接寻址,指的是“操作数”在段内的“偏移地址”由寄存器给出。 偏移地址寄存器是SI、DI、BX,默认的段地址是数据段寄存器DS。偏移地址寄存器是BP,默认的段地址是栈段寄存器SS。
1.1、段地址DS:SI、DI、BX ——> DS
1.2、段地址SS:BP ——> SS
2、寻址方式【段+偏移】:内存的绝对地址 = 段地址*16 + [ BX | SI | DI | BP ]
2.1、获取数据段数据DS: DS:BX;DS:SI
2.2、获取堆栈段数据SS: SS:BP;SS:SP
2.3、获取代码段数据CS: CS:IP
2.4、获取扩展段数据ES: EX:SI
2.5、可以使用前缀: MOV AX, CS[BX] ; 内存绝对地址(HEX) = CS*16 + BX
2、操作数,存储在内存中。操作数,存储在内存的“数据段”内。数据段的段地址必须存储在“寄存器DS”内。操作数在数据段内的偏移地址,由寄存器给出。
3、计算操作数在内存中的绝对地址:假设DS=1000H。BX=0000H。操作数在内存中的绝对地址 = DS*16 + BX = 10000H+0000H=10000H。
1 mov ax, 0000h
2 mov ds, ax
3 mov bx, 0
4 mov cx, [bx] ; 寄存器间接寻址
五、(内存寻址)寄存器相对寻址方式:
1、寄存器相对寻址:内存的绝对地址 = 段地址(DS;SS)*16 + (BX、SI、DI;BP) + BIAS(8位或16位偏移量;8bits或16bits)
1.1、段地址默认寄存器DS: DS:BX、DS:SI;
1.2、段地址默认寄存器ES: ES:DI
1.3、段地址默认寄存器SS: SS:BP;SS:SP
1.4、段地址默认寄存器CS(CS寄存器 - 不能用mov命令赋值): CS:IP
1.5、BIAS(偏移量): 8位二进制的偏移量(8btis),相当于“2位十六进制的数字”,例如:“FFH”、“08H”。16位二进制的偏移量(16bits),相当于“4位十六进制的数字”,例如:“FFFFH”、“10H”。
2、计算操作数在内存中的绝对地址:DS=1001H,BX=20H,BIAS=30H,则“操作数在内存中的绝对地址” = DS*16 + BX + BIAS = 10010H + 20H + 30H =10060H
1 mov ax, 1001h
2 mov,ds, ax
3 mov bx, 0020H
4 mov cx, [bx + 30h] ; 寄存器相对寻址方式
六、(内存寻址)基址加变址寻址方式:
1、基址加变址: 内存的绝对地址 = 段地址(DS;SS)*16 + 基址(BX;BP) + 变址(SI,DI)
1.1、BX:数据基址寄存器,默认段地址是数据段DS。BP:栈基址寄存器,默认段地址是栈段地址寄存器SS。SI,源变址寄存器,默认段地址是数据段地址寄存器DS。DI,目的变址寄存器,默认段地址是扩展段地址寄存器ES。
2、计算操作数在内存中的绝对地址:操作数在内存中的绝对地址 = DS*16 + BX + SI =11220H + 2233H + 3344H = 16797H
1 ; absolute_address = DS*16 + BX + SI
2 mov ax, 1122h
3 mov ds, ax
4 mov bx, 2233h
5 mov si, 3344h
6 mov cs, [bx+si] ; 基址变址寻址方式
七、(内存寻址)相对基址加变址寻址方式:
1、相对基址加变址: 内存的绝对地址 = 段地址(DS;SS)*16 + 基址(BX;BP) + 变址(SI,DI) + BIAS偏移量(8bits或16bits)
1.1、BX:数据基址寄存器,默认段地址是数据段DS。BP:栈基址寄存器,默认段地址是栈段地址寄存器SS。SI,源变址寄存器,默认段地址是数据段地址寄存器DS。DI,目的变址寄存器,默认段地址是扩展段地址寄存器ES。
1.2、BIAS(偏移量): 8位二进制的偏移量(8bits),相当于“2位十六进制的数字”,例如:“FFH”、“08H”。16位二进制的偏移量(16bits),相当于“4位十六进制的数字”,例如:“FFFFH”、“10H”。
2、计算操作数在内存中的绝对地址:操作数在内存中的绝对地址 = DS*16 + BX + SI +BIAS =11220H + 2233H + 3344H + 1000H = 17797H
1 ; absolute_address = DS*16 + BX + SI + BIAS
2 mov ax, 1122h
3 mov ds, ax
4 mov bx, 2233h
5 mov si, 3344h
6 mov cs, [bx+si+1000h] ; 相对基址变址寻址方式
八、参考资料:
1、七种寻址方式: https://blog.csdn.net/u011680118/article/details/45888603?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0-45888603-blog-127747321.pc_relevant_3mothn_strategy_and_data_recovery&spm=1001.2101.3001.4242.1&utm_relevant_index=3
2、七种数据寻址方式: https://blog.csdn.net/m0_74208186/article/details/127747321?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EYuanLiJiHua%7EPosition-2-127747321-blog-6213898.pc_relevant_recovery_v2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EYuanLiJiHua%7EPosition-2-127747321-blog-6213898.pc_relevant_recovery_v2&utm_relevant_index=5
3、bx,bp,si,di分别针对什么情况来使用: https://zhidao.baidu.com/question/1450486265262602420.html
4、求问IBM8086汇编语言中各通用寄存器的默认段: https://zhidao.baidu.com/question/1450486265262602420.html
本文由 lnlidawei 原创、整理、转载,本文来自于【博客园】; 整理和转载的文章的版权归属于【原创作者】; 转载或引用时请【保留文章的来源信息】:https://www.cnblogs.com/lnlidawei/p/17042680.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)