汇编语言---实验九---段间偏移
实验九的add ax,0ah为什么是偏移160字节,每段是16字节,而不是64KB 本帖最后由 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 毫无关系。 jackz007 发表于 2020-2-24 11:41
应该是 add ax,0a0h 吧?0a0h 是十六进制值,十进制值为 16 × 10 = 160,为什么是 160 呢?因为 D ...
的确是0ah,但因为是段间偏移,所以0ah就可以了,如果是段内偏移,才是00a0h djsk132 发表于 2020-2-24 15:35
的确是0ah,但因为是段间偏移,所以0ah就可以了,如果是段内偏移,才是00a0h
但我不知道为什么是16字节,而不是64KB一段
jackz007 发表于 2020-2-24 11:41
应该是 add ax,0a0h 吧?0a0h 是十六进制值,十进制值为 16 × 10 = 160,为什么是 160 呢?因为 D ...
我懂了,16字节和64KB是自己定义的,可以选择,但若64KB的话,就只能是在原位置进行段内偏移,而选择16字节,就可以从新定位段地址,再从零开始段内偏移,不知对不对? djsk132 发表于 2020-2-24 15:40
我懂了,16字节和64KB是自己定义的,可以选择,但若64KB的话,就只能是在原位置进行段内偏移,而选择16字 ...
还是有问题, jackz007 发表于 2020-2-24 11:41
应该是 add ax,0a0h 吧?0a0h 是十六进制值,十进制值为 16 × 10 = 160,为什么是 160 呢?因为 D ...
我又想了了一下,因为ax的值是给es的,即段寄存器,它将发生段间偏移,而不是段内偏移,然后就可以理解为什么是0ah,而不是0a0h了,但为什么是一段16字节,而不是64KB? 本帖最后由 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 也是等效的,前面所讲的那些道理也是仍然有效的! 本帖最后由 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.如果每一段的大小没有规定,可以任意选择,那以后索引索引数据不就很麻烦了? 本帖最后由 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,所以,对应于同一个内存地址,用段加偏移可以有很多完全不同的表达形式。
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 ,ax
mov ax,4c00h
int 21h
code ends
end start
本帖最后由 jackz007 于 2020-2-24 17:56 编辑
b800:0 开始的内存是显存,其内容和屏幕当前显示内容有关,在你操作 debug 的过程中,屏显内容显然是处于不断变化中的,所以,你不能通过这个方法来验证我所说的道理。必须换一个地址来测试。你可以选择 0040:0000 ,这个区域属于DOS 操作系统,F000:0000,这个区域属于 BIOS,这些内存的内容肯定不全为 00,而且,都是相对固定的。
嗯,知道了 什么鬼,实验九是什么?add ax,你加的是ax,你接着想干什么? kankan 之前的没问题了,但有一个新问题:
但假如我要在连续的两个段内获取这两个段对应的第10个和第1个的字节的数据,该怎么通过段地址表示? 哪里定义了每段是16字节了啊?
不管段地址是什么,目标地址都可以表示成:段地址X16+偏移地址,而偏移地址是一个16位的二级制数,所以偏移地址的范围是0000h~FFFFh,可以表示2^16=64kB的地址空间。
当段地址是0aH时,该段的地址空间为00a00~1009F,段空间依然是64kB啊。 应该是000a0~1009f,这个我明白,
段地址的*16,左偏移1,提供16B的空间来让偏移量来定位,而偏移量是16位,寻址能力是64KB,但他的寻址能力是跨越了多个段基址,
假如我只用偏移量来寻址16B的大小,然后16B后根据上一个段基址重新定位一个段基址,通过该段基址来定位接下来的16B内容,但为什么
段地址1:【10】的物理地址 等于 段地址2:【0】的物理地址?
他们不应该表示不同的物理地址吗?
页:
[1]