找回密码
 register

QQ登录

只需一步,快速开始

查看: 51|回复: 1

[汇编语言] [零基础入门学习]·13·寄存器(内存访问)·mov、add、sub指令·数据段·3.1~3.5小结·检测点3.1

[复制链接]

[汇编语言] [零基础入门学习]·13·寄存器(内存访问)·mov、add、sub指令·数据段·3.1~3.5小结·检测点3.1

[复制链接]
  • 打卡等级:热心大叔
  • 打卡总天数:91
  • 打卡月天数:14
  • 打卡总奖励:91
  • 最近打卡:2025-01-15 02:59:34
Waylee

主题

0

回帖

1万

积分

仙帝

积分
11890
Waylee 2024-12-26 23:59 | 显示全部楼层 |阅读模式 | Google Chrome | Windows 10

马上注册,查看网站隐藏内容!!

您需要 登录 才可以下载或查看,没有账号?register

×

3.4 mov、add、sub指令

前面我们用到了 mov、add、sub指令,它们都带有两个操作对象。

mov 寄存器,数据           比如:mov ax,8
mov 寄存器,寄存器       比如:mov ax,bx
mov 寄存器,内存单元    比如:mov ax,[0]
mov 内存单元,寄存器    比如:mov [0],ax
mov 段寄存器,寄存器    比如:mov ds,ax

我们可以根据这些已知指令进行下面的推测。

(1)既然有“mov 段寄存器,寄存器”,从寄存器向段寄存器传送数据,那么也应该有“mov 寄存器,段寄存器”,从段寄存器向寄存器传送数据。一个合理的假设是:8086CPU内存有寄存器到段寄存器的通路,那么也应该有相反的通路。

有了推测,我们还要验证一下。进入Debug,用A命令,如图3.4所示。

001.webp

图3.4中,用A指令在一个预设的地址0B39:0100处,用汇编的形式mov ax,ds 写入指令,再用T命令执行,可以看到执行的结果,段寄存器ds中的值送到了寄存器ax中。通过验证我们知道,“mov 寄存器,段寄存器”是正确的指令。

(2)既然有“mov 内存单元,寄存器”,从寄存器向内存单元传送数据,那么也应该有“mov 内存单元,段寄存器”,从段寄存器向内存单元传送数据。比如我们将段寄存器cs中的内容送入内存10000H处,指令如下。

mov ax,1000H
mov ds,ax
mov [0],cs

在Debug中进行试验,如图3.5所示。

3.5

3.5

图3.5中,当CS:IP指向0B39:0105的时候,Debug显示当前的指令mov [0000],cs,因为这是一条访问内存的指令,Debug还显示出指令要访问的内存单元中的内容。由于指令中的CS是一个16位寄存器,所以要访问(写入)的内存单元是一个字单元,它的偏移地址为0,段地址在ds中,Debug在屏幕右边显示“DS:0000=0000”,我们可以知道这个字单元中的内容为0。

mov [0000],cs 执行后,CS中的数据(0B39H)被写入1000:0处,1000:1单元存放0BH,1000:0单元存放39H。

最后,用D命令从1000:0开始查看指令执行后内存中的情况,注意1000:0、1000:1两个单元的内容。

(3)“mov 段寄存器,内存单元”也应该可行,比如我们可以用10000H处存放的字型数据设置ds(即将10000H处存放的字型数据送入ds),指令如下。

mov ax,1000H
mov ds,ax
mov ds,[0]

可以自行在Debug中进行试验。

add和sub指令同mov一样,都有两个操作对象。它们也可以有以下几种形式。

add 寄存器,数据          比如:add ax,8
add 寄存器,寄存器         比如:add ax,bx
add 寄存器,内存单元    比如:add ax,[0]
add 内存单元,寄存器    比如:add [0],ax
sub 寄存器,数据          比如:sub ax,8
sub 寄存器,寄存器         比如:sub ax,bx
sub 寄存器,内存单元    比如:sub ax,[0]
sub 内存单元,寄存器    比如:sub [0],ax

它们可以对段寄存器进行操作吗?比如“add as,ax”。请自行在Debug中是试验。

3.5 数据段

前面讲过(参见2.8节),对于8086PC机,在编程时,可以根据需要,将一组内存单元定义为一个段。我们可以将一组长度为N(N≤64KB)、地址连续,起始地址为16的倍数的内存单元当做专门存储数据的内存空间,从而定义了一个数据段。比如用123B0H~123B9H这段内存空间来存放数据,我们就可以认为,123B0H~123B9H这段内存是一个数据段,它的段地址为123BH,长度为10个字节。

如何访问数据段中的数据呢?将一段内存当作数据段,是我们在编程时的一种安排,可以在具体操作的时候,用ds存放数据段的段地址,再根据需要,用相关指令访问数据段中的具体单元。

比如,将123B0H~123B9H的内存单元定义为数据段。现在要累加这个数据段中的前3个单元中的数据,代码如下。

mov ax,123BH
mov ds,ax       ;将123BH送入ds中,作为数据段的段地址
mov al,0        ;用al存放累加的结果
add al,[0]      ;将数据段第一个单元(偏移地址为0)中的数值加到al中 
add al,[1]      ;将数据段第二个单元(偏移地址为1)中的数值加到al中 
add al,[2]      ;将数据段第三个单元(偏移地址为2)中的数值加到al中 

问题 3.5

写几条指令,累加数据段中的前3个字型数据,思考后看分析。
分析
代码如下。

mov ax,123BH
mov ds,ax       ;将123BH送入ds中,作为数据段的段地址
mov ax,0        ;用ax存放累加的结果
add ax,[0]      ;将数据段第一个字(偏移地址为0)加到ax中
add ax,[2]      ;将数据段第二个字(偏移地址为2)加到ax中
add ax,[4]      ;将数据段第三个字(偏移地址为4)加到ax中

注意,一个字型数据占两个单元,所以偏移地址是0、2、4。

3.1~3.5小结

  1. 字在内存中存储时,要用两个地址连续的内存单元来存放,字的低位字节存放在低地址单元中,高位字节存放在高地址单元中。
  2. 用mov指令访问内存单元,可以在mov指令中只给出单元的偏移地址,此时,段地址默认在DS寄存器中。
  3. [address]表示一个偏移地址为address的内存单元。
  4. 在内存和寄存器之间传送字型数据时,高地址单元和高8位寄存器、地地址单元和低8位寄存器相对于。
  5. mov、add、sub是具有两个操作对象的指令。jmp是具有一个操作对象的指令。
  6. 可以根据自己的猜测,在Debug中实验指令的新格式。

检测点 3.1

一、在Debug中,用“d 0:0 1f”查看内存,结果如下。

0000:0000 70 80 F0 30 EF 60 30 E2-00 80 80 12 66 20 22 60
0000:0010 62 26 E6 D6 CC 2E 3C 3B-AB BA 00 00 26 06 66 88

下面的程序执行前,AX=0,BX=0,写出每条汇编指令执行完后相关寄存器中的值。

mov ax,1            
mov ds,ax
mov ax,[0000]       ;AX=________
mov bx,[0001]       ;BX=________
mov ax,bx           ;AX=________
mov ax,[0000]       ;AX=________
mov bx,[0002]       ;BX=________
add ax,bx           ;AX=________
add ax,[0004]       ;AX=________
mov ax,0            ;AX=________
mov al,[0002]       ;AX=________
mov bx,0            ;BX=________
mov bl,[000C]       ;BX=________
add al,bl           ;AX=________

提示,注意ds的设置。

二、内存中的情况如下3.6所示。

各寄存器的初始值:CS=2000H,IP=0,DS=1000H,AX=0,BX=0;
①写出CPU执行的指令顺序(用汇编指令写出)。
②写出CPU执行每条指令后,CS、IP和相关寄存器中的数值。
③再次体会:数据和程序有区别吗?如何确定内存中的信息哪些是数据,哪些是程序?

002.webp

没有通过检测点请不要向下学习!
做完后再看二楼的参考答案

  • 打卡等级:热心大叔
  • 打卡总天数:91
  • 打卡月天数:14
  • 打卡总奖励:91
  • 最近打卡:2025-01-15 02:59:34
楼主
Waylee 楼主

主题

0

回帖

1万

积分

仙帝

积分
11890
Waylee 2024-12-27 16:38 | 显示全部楼层 | Google Chrome | Windows 10

检测点 3.1 参考答案

一、在Debug中,用“d 0:0 1f”查看内存,结果如下。

0000:0000 70 80 F0 30 EF 60 30 E2-00 80 80 12 66 20 22 60
0000:0010 62 26 E6 D6 CC 2E 3C 3B-AB BA 00 00 26 06 66 88

下面的程序执行前,AX=0,BX=0,写出每条汇编指令执行完后相关寄存器中的值。

mov ax,1            
mov ds,ax
mov ax,[0000]       ;AX=2662H
mov bx,[0001]       ;BX=E626H
mov ax,bx           ;AX=E626H
mov ax,[0000]       ;AX=2662H
mov bx,[0002]       ;BX=D6E6H
add ax,bx           ;AX=FD48H
add ax,[0004]       ;AX=2C14H
mov ax,0            ;AX=0000H
mov al,[0002]       ;AX=00E6H
mov bx,0            ;BX=0000H
mov bl,[000C]       ;BX=0026H
add al,bl           ;AX=000CH 注:由于al是8位的,所以出现溢出,进位舍去,故ax=000CH

提示,注意ds的设置。

二、内存中的情况如下3.6所示。

各寄存器的初始值:CS=2000H,IP=0,DS=1000H,AX=0,BX=0;
①写出CPU执行的指令顺序(用汇编指令写出)。
答:
由题意知,CS:IP = 2000:0000,指向内存地址 = CS << 4 + IP = 20000H + 0000H = 20000H
根据内存情况可知,指向指令为 mov ax,6622H
下一条指令为 jmp 0FF0:0100
由于这一条指令为跳转指令 故执行后 CS:IP 更改为 0FF0:0100,指向内存地址 = CS << 4 + IP = 0FF00H + 0100H = 10000H
根据内存情况可知下一条指令为 mov ax,2000H
下一条指令为 mov ds,ax
下一条指令为 mov ax,[0008]
下一条指令为 mov ax,[0002]
故CPU指令的执行序列为:

mov ax,6622H
jmp 0ff0:0100
mov ax,2000H
mov ds,ax
mov ax,[0008]
mov ax,[0002]

②写出CPU执行每条指令后,CS、IP和相关寄存器中的数值。
答:
注:在每条指令读取后、执行后这个阶段,CS和IP的值会发生变化。而不是在指令执行后发生变化,注意第二条指令 读取前、执行后、执行后 CS和IP的变化

指令 CS(读取前) IP(读取前) DS(执行后) AX(执行后) CS(执行后) IP(执行后)
mov ax,6622H 2000H 0000H 1000H 6622H 2000H 0003H
jmp 0ff0:0100 2000H 0003H 1000H 6622H 2000H(转跳后为0FF0H) 0008H(转跳后为0100H)
mov ax,2000H 0FF0H 0100H 1000H 2000H 0FF0H 0103H
mov ds,ax 0FF0H 0103H 2000H 2000H 0FF0H 0105H
mov ax,[0008] 0FF0H 0105H 2000H C389H 0FF0H 0108H
mov ax,[0002] 0FF0H 0108H 2000H EA66H 0FF0H 010BH

003.webp

③再次体会:数据和程序有区别吗?如何确定内存中的信息哪些是数据,哪些是程序?
答:
指令和数据没有区别,都是二进制数据。被CS:IP指向的内存单元中的内容为指定

您需要登录后才可以回帖 登录 | register

本版积分规则

雪舞知识库 | 浙ICP备15015590号-1 | 萌ICP备20232229号|浙公网安备33048102000118号 |天天打卡

GMT+8, 2025-1-15 17:42 , Processed in 0.109166 second(s), 7 queries , Redis On.

Powered by XueWu Licensed

Copyright © Tencent Cloud.

快速回复 返回顶部 返回列表