关于多段汇编语言地址的问题

有为少年 2017-09-12 06:26:29
       
assume cs:code,ds:data,ss:stack

data segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
data ends

stack segment
dw 0,0,0,0,0,0,0,0
stack ends

code segment
start: mov ax,stack
mov ss,ax
mov sp,16

mov ax,code

mov ax,data
mov ds,ax

push ds:[0]
push ds:[2]
pop ds:[2]
pop ds:[0]

mov ax,4c00h
int 21h

code ends
end start





CPU执行程序,程序返回前,cs,ss,ds与code,stack,data所指代的地址为什么code是一致,而后两者不同,而且差值也不同?

...全文
453 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
有为少年 2017-09-14
  • 打赏
  • 举报
回复
http://bbs.csdn.net/topics/390171677


其实我描述的可能有问题,但是我找见上面的一个帖子,正中我的下怀,所以想把我真正的问题表述出来。但是先感谢过各位。



引用
理解: assume cs:code, ds:data,ss:stack

这句的含义具体是什么呢?

1、编译,连接 使用 debug调试,最开始就使用 r 命令以及u 命令查看寄存器结果以及代码对应如下:

DS = 075a SS = 0769 CS = 076c
data=076a stack=076b code=076c

这个结果我感觉很意外。

忽然想到,DS,SS,CS的默认开始值是谁,以及怎么指定的?他们的间隔值就单论开始的时候,有没有什么固定关系?
看来 assume 对此并无影响?
还有,data,stack,code的对应的地址是谁,以及怎么指定的?他们的间隔值为什么是1h?


2 、使用d ds:0查看内存结果如下:
-d ds:0
14AB:0000 CD 20 FF 9F 00 9A F0 FE-1D F0 4F 03 76 0E 8A 03
这个结果我感到很不理解, 如果说ds保存的是data段的段地址,那么 d ds:0查看到得数据应该是在程序中定义的数据:
0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h。 可是显然我查询得到的数据和定义的数据没半毛钱关系,ds不是应该存放的是data段的段地址码?查出来的应该是data段的数据才对啊

》》》》》》》》》》》》》》》》》》
》》》》这个我现在明白了,是psp部分。
》》》》》》》》》》》》》》》》》》


3、使用d ss:0 查看堆栈段数据结果如下:


ss:0000 开始的16个字节存放的是什么数据:

接下来的16个字节里,,data的数据为什么会出现

而之后的 ss:0020开始的16个字节才是堆栈数据:
0,0,0,0,0,0,0,0
赵4老师 2017-09-13
  • 打赏
  • 举报
回复
建议研究一下DOS加载.COM或.EXE对应的汇编代码。
李伯特 2017-09-13
  • 打赏
  • 举报
回复
DS:0x075A:0x0000 SS:0x075B:0x0000 CS:0x075B:0x0000 而且此处。内存分配是连续分配,也就说紧接着数据段后面就是栈段,紧接着栈段之后就是CS段,这样就可以起到保护作用,当数据访问越段时就需要格外当心,但是在段内就可随意访问了
李伯特 2017-09-13
  • 打赏
  • 举报
回复
计算机的内存管理单元是以“字节”为最小单位进行线性编址的,字节是80x86CPU对内存管理的基元。为了标识每个存储单元,就给每个存储单元规定一个编号,该编号就是内存单元的物理地址。 存储单元的物理地址是一个16位的二进制数,物理地址通常采用16进制书写。 16位CPU内部拥有20根地址线,它的寻址范围就是2的20次方,也就是1M的内存空间。 但是16位CPU存放存储单元偏移量的寄存器(IP,SP,BP,SI,DI,BX)的编码范围仅为:00000H - 0FFFFH,也就是只能访问65536个存储单元,64K。 为了能够访问1M的内存空间,CPU就采用了内存分段的管理模式,并且在CPU内部加入了段寄存器。 首先说的是段寄存器的大小是16位的,其中放的是段值。一个物理地址的计算是段值*段的大小+段内偏移=1M;而段内偏移的范围是地址线位数或者指针寄存器的大小决定的,所以它的范围是0-64K。当为0时也就是段的起始地址,所以此时段的大小最小为16.否则不能等于1M。所以我认为既然是为了用16位表示20位的地址空间而采用的分段,所以段的 起始地址肯定就是16的倍数了。 参考:80x86,完整的地址当初被设计为 段址*16+偏址,所以就要求段对齐在 16 的倍数上了。定为 16 应该是和当时内存容量的预期有关。这样的地址形成方式可以访问到 1M 的内存空间。
zara 2017-09-13
  • 打赏
  • 举报
回复
对 .exe 类的来说,程序刚载入时,CS:IP 指向你程序的入口;SS:SP,如果你的堆栈段定义用了 STACK 修饰(mystack segment stack),则也会指向到你的栈;DS 和 ES 则是指向 PSP,后面指向哪里需要你自己的代码来做。
有为少年 2017-09-12
  • 打赏
  • 举报
回复
经过我的研究,发现上面的研究过程有点小问题。

首先,ss在后面有个赋值,我没有执行到那一步去看。

再者忘记了在程序内存中,还有PSP这么个特别的东西。

整理了一下,在我的模拟环境中,上面程序,执行到最后,有如下内存结构分布。



所以说,可见,ss最后和stack是一致的,ds+10h(psp长度)= data,cs = code

但是我又想到,这里的cs与code的相等并未明确赋值,而ss,ds都有对应的mov语句将他们改动到了stack,data上,
所以我想知道,stack实际指向的是什么?data指向什么?code应该是和cs一样的吧。

21,458

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧