鱼C论坛

 找回密码
 立即注册
查看: 3096|回复: 17

[已解决]汇编语言---实验九---段间偏移

[复制链接]
发表于 2020-2-24 11:24:47 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
实验九的add ax,0ah为什么是偏移160字节,每段是16字节,而不是64KB
最佳答案
2020-2-24 11:41:15
本帖最后由 jackz007 于 2020-2-24 12:59 编辑

        应该是 add ax,0a0h 吧?0a0h 是十六进制值,十进制值为 16 × 10 = 160,为什么是 160 呢?因为 DOS 窗口每行显示 80 个字符,如果通过向显示缓存 0b800h:0 地址传送数据进行显示,那么,屏幕上的每一个字符占用 2 个字节,其中,第一个字节是字符本身,第二个字节是字符颜色编码,这样,屏幕上一行数据占用的内存总量就恰好是 80 x 2 = 160 字节。所以,指令 add ax,0a0h 的作用就是跨过一行的显示,直接定位到下一行,与一个段是不是 64 kb 毫无关系。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-2-24 11:41:15 | 显示全部楼层    本楼为最佳答案   
本帖最后由 jackz007 于 2020-2-24 12:59 编辑

        应该是 add ax,0a0h 吧?0a0h 是十六进制值,十进制值为 16 × 10 = 160,为什么是 160 呢?因为 DOS 窗口每行显示 80 个字符,如果通过向显示缓存 0b800h:0 地址传送数据进行显示,那么,屏幕上的每一个字符占用 2 个字节,其中,第一个字节是字符本身,第二个字节是字符颜色编码,这样,屏幕上一行数据占用的内存总量就恰好是 80 x 2 = 160 字节。所以,指令 add ax,0a0h 的作用就是跨过一行的显示,直接定位到下一行,与一个段是不是 64 kb 毫无关系。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2020-2-24 15:35:37 | 显示全部楼层
jackz007 发表于 2020-2-24 11:41
应该是 add ax,0a0h 吧?0a0h 是十六进制值,十进制值为 16 × 10 = 160,为什么是 160 呢?因为 D ...

的确是0ah,但因为是段间偏移,所以0ah就可以了,如果是段内偏移,才是00a0h
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-2-24 15:36:20 | 显示全部楼层
djsk132 发表于 2020-2-24 15:35
的确是0ah,但因为是段间偏移,所以0ah就可以了,如果是段内偏移,才是00a0h

但我不知道为什么是16字节,而不是64KB一段
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-2-24 15:40:30 | 显示全部楼层
jackz007 发表于 2020-2-24 11:41
应该是 add ax,0a0h 吧?0a0h 是十六进制值,十进制值为 16 × 10 = 160,为什么是 160 呢?因为 D ...

我懂了,16字节和64KB是自己定义的,可以选择,但若64KB的话,就只能是在原位置进行段内偏移,而选择16字节,就可以从新定位段地址,再从零开始段内偏移,不知对不对?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-2-24 15:46:20 | 显示全部楼层
djsk132 发表于 2020-2-24 15:40
我懂了,16字节和64KB是自己定义的,可以选择,但若64KB的话,就只能是在原位置进行段内偏移,而选择16字 ...

还是有问题,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-2-24 15:53:08 | 显示全部楼层
jackz007 发表于 2020-2-24 11:41
应该是 add ax,0a0h 吧?0a0h 是十六进制值,十进制值为 16 × 10 = 160,为什么是 160 呢?因为 D ...

我又想了了一下,因为ax的值是给es的,即段寄存器,它将发生段间偏移,而不是段内偏移,然后就可以理解为什么是0ah,而不是0a0h了,但为什么是一段16字节,而不是64KB?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-2-24 16:10:38 | 显示全部楼层
本帖最后由 jackz007 于 2020-2-24 19:35 编辑
djsk132 发表于 2020-2-24 15:53
我又想了了一下,因为ax的值是给es的,即段寄存器,它将发生段间偏移,而不是段内偏移,然后就可以理解为 ...


      你应该记得把用 段 + 偏移 方式表达的内存地址换算成绝对地址的计算公式吧?
    绝对地址 = 段地址 × 10h + 偏移地址
      通过这个公式我们可以知道,段地址每增加 1,与偏移地址增加 10h(16字节) 是等效的,举例来说:
B800:0160
      与
B810:0060
      及
B816:0000
      表达的是同一个地址:0B8160H,当然,这个值用一个 word (双字节)无法表达,必须拆解成段 + 偏移的形式。
      
      所以,在本例中,段地址增加 0ah 与偏移地址增加 0a0h 也是等效的,前面所讲的那些道理也是仍然有效的!  
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-2-24 16:17:26 | 显示全部楼层
本帖最后由 djsk132 于 2020-2-24 16:18 编辑
jackz007 发表于 2020-2-24 16:10
你应该记得把用 段 + 偏移 方式表达的内存地址换算成绝对地址的计算公式吧?

      通过这个 ...


01.  cpu为16位 而物理地址是20位 所以将地址空间分段。将其地址空间分位若干个64KB的段,最大64KB,最小16B。这是网上看到的,实验九为什么用一段16字节,而不是64KB
02.  你是通过debug获取0B8160h的地址,但因为不同段,在内存单元的位置就不同,虽然都是0B8160h
03.  如果每一段的大小没有规定,可以任意选择,那以后索引索引数据不就很麻烦了?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-2-24 16:29:14 | 显示全部楼层
本帖最后由 jackz007 于 2020-2-24 16:37 编辑
djsk132 发表于 2020-2-24 16:17
01.  cpu为16位 而物理地址是20位 所以将地址空间分段。将其地址空间分位若干个64KB的段,最大64KB,最 ...


      段 + 偏移 仅仅是一种表达20位内存地址的方式,段只是一个虚拟的概念而已,物理上是根本不存在的,知道就好,不必过于拘泥。
      如果不信,你可以用 debug 观察一下
d 0000:0300 l10
d 0004:02c0 l10
d 0030:0000 l10
      看看显示的内容是不是完全一样?
      事实证明,这些不同的表达方式 0000:0300、0004:02c0、0030:0000 殊途同归,表达的都是同一个内存地址 00300h,所以,对应于同一个内存地址,用段加偏移可以有很多完全不同的表达形式。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-2-24 17:09:28 | 显示全部楼层
jackz007 发表于 2020-2-24 16:29
段 + 偏移 仅仅是一种表达20位内存地址的方式,段只是一个虚拟的概念而已,物理上是根本不存在的 ...

B816H:10   B8170
B817H:0    B8170
DB170处的值
这个是不是一样,我电脑debug不行

assume cs:code,ds:data,ss:stack
data segment   
db 10 dup(02h)
data ends
code segment
start:
mov ax,data
mov ds,ax
add ax,1H
mov ds,ax
mov ax,24H
mov [0],ax

mov ax,4c00h
int 21h
code ends
end start
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-2-24 17:54:35 | 显示全部楼层
本帖最后由 jackz007 于 2020-2-24 17:56 编辑

        b800:0 开始的内存是显存,其内容和屏幕当前显示内容有关,在你操作 debug 的过程中,屏显内容显然是处于不断变化中的,所以,你不能通过这个方法来验证我所说的道理。必须换一个地址来测试。你可以选择 0040:0000 ,这个区域属于DOS 操作系统,F000:0000,这个区域属于 BIOS,这些内存的内容肯定不全为 00,而且,都是相对固定的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-2-24 18:09:37 | 显示全部楼层
嗯,知道了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-2-24 19:31:07 | 显示全部楼层
什么鬼,实验九是什么?add ax,你加的是ax,你接着想干什么?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-2-24 22:48:47 | 显示全部楼层
kankan
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-2-25 00:03:05 | 显示全部楼层
之前的没问题了,但有一个新问题:
但假如我要在连续的两个段内获取这两个段对应的第10个和第1个的字节的数据,该怎么通过段地址表示?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-2-25 00:28:50 | 显示全部楼层
哪里定义了每段是16字节了啊?
不管段地址是什么,目标地址都可以表示成:段地址X16+偏移地址,而偏移地址是一个16位的二级制数,所以偏移地址的范围是0000h~FFFFh,可以表示2^16=64kB的地址空间。
当段地址是0aH时,该段的地址空间为00a00~1009F,段空间依然是64kB啊。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-2-25 11:34:27 | 显示全部楼层
应该是000a0~1009f,这个我明白,
段地址的*16,左偏移1,提供16B的空间来让偏移量来定位,而偏移量是16位,寻址能力是64KB,但他的寻址能力是跨越了多个段基址,
假如我只用偏移量来寻址16B的大小,然后16B后根据上一个段基址重新定位一个段基址,通过该段基址来定位接下来的16B内容,但为什么
         段地址1:【10】的物理地址   等于   段地址2:【0】的物理地址?
他们不应该表示不同的物理地址吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-25 00:09

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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