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

时间:2022-06-26 01:25:09
       
        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是一致,而后两者不同,而且差值也不同?

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

6 个解决方案

#1


经过我的研究,发现上面的研究过程有点小问题。

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

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

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

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

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

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

#2


对 .exe 类的来说,程序刚载入时,CS:IP 指向你程序的入口;SS:SP,如果你的堆栈段定义用了 STACK 修饰(mystack segment   stack),则也会指向到你的栈;DS 和 ES 则是指向 PSP,后面指向哪里需要你自己的代码来做。

#3


计算机的内存管理单元是以“字节”为最小单位进行线性编址的,字节是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 的内存空间。

#4


DS:0x075A:0x0000
SS:0x075B:0x0000
CS:0x075B:0x0000
而且此处。内存分配是连续分配,也就说紧接着数据段后面就是栈段,紧接着栈段之后就是CS段,这样就可以起到保护作用,当数据访问越段时就需要格外当心,但是在段内就可随意访问了

#5


建议研究一下DOS加载.COM或.EXE对应的汇编代码。

#6


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

#1


经过我的研究,发现上面的研究过程有点小问题。

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

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

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

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

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

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

#2


对 .exe 类的来说,程序刚载入时,CS:IP 指向你程序的入口;SS:SP,如果你的堆栈段定义用了 STACK 修饰(mystack segment   stack),则也会指向到你的栈;DS 和 ES 则是指向 PSP,后面指向哪里需要你自己的代码来做。

#3


计算机的内存管理单元是以“字节”为最小单位进行线性编址的,字节是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 的内存空间。

#4


DS:0x075A:0x0000
SS:0x075B:0x0000
CS:0x075B:0x0000
而且此处。内存分配是连续分配,也就说紧接着数据段后面就是栈段,紧接着栈段之后就是CS段,这样就可以起到保护作用,当数据访问越段时就需要格外当心,但是在段内就可随意访问了

#5


建议研究一下DOS加载.COM或.EXE对应的汇编代码。

#6


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