丶Haw 发表于 2012-7-14 00:18:42

实验5(3)

assume cs:code,ds:data,ss:stack ;执行前ds=0c55,es= 0c55,cs=oc65,ss=0c65

code segment      ; 0c68:0 23 01 56 04这里 cs=0c68?

start:mov ax,stack ;0C86:0000 B88A0C   stack=0c69?why?为什么是加4?

      mov ss,ax       ;0C86:0003 8ED0

      mov sp,16   ;0C86:0005 BC1000

      mov ax,data;0C86:0008 B8890C    data=0c68?why?为什么是加3?

      mov ds,ax   ;0C86:000B 8ED8

      push ds:      ;0C86:000D FF360000 ds:0=0123   oc68:0 3 23 01 56 04

      push ds:       ;0C86:0011 FF360200入栈后,ss里面放的是什么?

      pop ds:      ;0C86:0015 8F060200出栈后,ss里面又是放的什么澹?

      pop ds:       ;0C86:0019 8F060000

      mov ax,4c00h ;0C86:001D B8004C

      int 21h

code ends

data segment

      dw 0123h,0456h

data ends

stack segment

      dw 0,0

stack ends

end start


向往 发表于 2012-7-14 00:18:43

丶Haw 发表于 2012-7-16 01:34 static/image/common/back.gif
5.push 的意思不是把ds:0的内容放入 ss:sp中么?为什么0c69:000e 000f的内容不是01 23?
6.pop 的 ...

5.push 的意思不是把ds:0的内容放入 ss:sp中么?
答:是

为什么0c69:000e 000f的内容不是01 23?
答:push 指令执行之后, 是23, 是01 (注意高,低位)
      push 执行前, pop 指令执行后, 和有可能是其他数据(有可能是一些中断信息)

6.pop 的意思就是从ss:sp中取出放入ds:0中?
答:是



向往 发表于 2012-7-14 02:15:43

本帖最后由 向往 于 2012-7-14 02:25 编辑

`
1. 执行前ds=0c55,es= 0c55,cs=oc65,ss=0c65
执行前, es, ss 的内容都是你系统的默认值, 并非你程序里面指定的段地址
而ds:0000 指向的是psp区域, cs:ip指向的是code段的起始位置

2. 0c68:0 23 01 56 04这里 cs=0c68?
不是, cs就是执行前的0c65, 而0c68是data段的段地址ds

3. stack=0c69?why?为什么是加4?
这个是根据你定义不同的段(code段, data段, stack段)的时候, 系统按照你所定义的先后顺序, 来为你分配段地址的.
你定义的第一个是code段, 占用字节为N, 则code段的需要的大小为 16*(N/16+1) 个字节, 估计(- - 抱歉, 这里说的我都糊涂了...)code段占用了段地址为0C65, 0C66, 0C67的3段空间, 所以data段的段地址ds是下一个, 也就是0c68, 同理, stack段也是这样, ss = 0c69

4. data=0c68?why?为什么是加3?
同上

5. 入栈后,ss里面放的是什么?
不管入栈还是出栈, ss都是不变的, 一直都是栈段的段地址

6. 出栈后,ss里面又是放的什么?
同上



如果解释得不妥, 麻烦楼下的鱼油补充, 多多指教!!!


`

丶Haw 发表于 2012-7-16 01:21:59

向往 发表于 2012-7-14 02:15 static/image/common/back.gif
`
1. 执行前ds=0c55,es= 0c55,cs=oc65,ss=0c65
执行前, es, ss 的内容都是你系统的默认值, 并非你程序里面 ...

首先非常感谢你!
但还有点不懂的。
3.code段占用了段地址为0C65, 0C66, 0C67的3段空间?为什么是3段空间?
5.入栈后,SS里面的内容,而不是指SS的地址
6.出栈后,SS里面的内容,而不是指SS的地址

丶Haw 发表于 2012-7-16 01:28:16

向往 发表于 2012-7-14 02:15 static/image/common/back.gif
`
1. 执行前ds=0c55,es= 0c55,cs=oc65,ss=0c65
执行前, es, ss 的内容都是你系统的默认值, 并非你程序里面 ...

5.push 的意思不是把ds:0的内容放入 ss:sp中么?
6.pop 的意思就是从ss:sp中取出放入ds:0中?
是不是这样,谢谢!

丶Haw 发表于 2012-7-16 01:34:48

向往 发表于 2012-7-14 02:15 static/image/common/back.gif
`
1. 执行前ds=0c55,es= 0c55,cs=oc65,ss=0c65
执行前, es, ss 的内容都是你系统的默认值, 并非你程序里面 ...

5.push 的意思不是把ds:0的内容放入 ss:sp中么?为什么0c69:000e 000f的内容不是01 23?
6.pop 的意思就是从ss:sp中取出放入ds:0中?
是不是这样,谢谢!

向往 发表于 2012-7-16 14:33:24

RE: 实验5(3)

本帖最后由 向往 于 2012-7-16 14:38 编辑

丶Haw 发表于 2012-7-16 01:21 http://bbs.fishc.com/static/image/common/back.gif
首先非常感谢你!
但还有点不懂的。
3.code段占用了段地址为0C65, 0C66, 0C67的3段空间?为什么是3段空 ...

对CPU来说, 内存空间是呈线性结构的.什么code, data, stack段都是人为区分给编译器分析的,cpu并不知道,也不会知道,更加不会懂.

code段的指令(代码)在载入内存之后, 每条指令都有其对应的机器码, 机器码也是数据, 当然也会占用空间.

那么, 内存究竟需要提供多少空间来存放code段中的数据呢?
那就要看你code段中到底有多少数据(指令/代码)
CPU为code段(其他段也一样的)分配的内存空间的计算公式为:    16*(N/16+1)
N是数据的占用具体的字节数量, 比如code段只有一条指令:
mov ax, 1234h
其机器码为b8 34 12,一共3个字节
那么这code段占用的内存空间并不是只有3字节, 而是 16*(3/16+1)=16个字节(段的大小总是16的倍数)

一个段大小的上限是65536个字节(64KB), 但是实验5.3中的code段怎么算也不可能占用了3个64kb那么大的空间,那为什么会是0c65, 0c66, 0c67这3个段地址呢?!
别忘了, 一个内存地址可以有多种不同的段地址和偏移地址组成(详情请参考书本24页下方的"小结")
由此可以看出, 0c65, 0c66, 0c67这3个"段"是为了更加方便我们的调试和查看内存中的数据

另外,以上都只是我个人的理解, 希望对你有帮助吧, 如有解释不妥之处, 请鱼友们尽管指出, 谢谢!!!



吃货YA鸭 发表于 2017-6-14 09:18:14

首先来分析一下,0c65, 0c66, 0c67这3个"段"地址,转换为物理(假定偏移地址为0)地址为0c650,0c660,0c670,可以解析为:0c65:0,0c65:10,0c65:20,也就是说你请求分配的数据空间和桟空间都有16个字节(转换16进制为10,也就是说每个段相差10)。

吃货YA鸭 发表于 2017-6-14 11:17:12

本帖最后由 吃货YA鸭 于 2017-6-14 11:22 编辑

楼主的问题:
1.stack=0c69?why?为什么是加4?
2.data=0c68?why?为什么是加3?
3.入栈后,ss里面放的是什么?
4.出栈后,ss里面又是放的什么澹?
已知初始化运行:ds=0c55,es= 0c55,cs=oc65,ss=0c65
可以理解为程序会从头到尾的先运行一遍你的代码,并且在其中找到你的程序入口,根据你的需要分配数据空间,桟空间。首先看这段代码中先是code段,之后是data段,然后是stack段。运用空间占用(=16*(N/16 +1))得到他们(data,stack)的占用空间,都是8字(16字节).
现在已经找到了程序入口,cs默认设置为入口处,因为data和stack在code代码后,所以你要知道,你的code指令占用了多少字节,因为初始cs+指令占用的空间才=data所在的空间.data的段+data空间才=stack的所在段空间.
在这段程序中,你要是会一个命令一个命令的计算,加一下就能知道,code占用了多大的空间了,
不会的话用debug调试,用-u 计算所有字节的总数,在这段程序中,字节总数为34位,
我觉计算机应该是以每16字节为一组,34位超出2位,默认给这2位分配了一个16字节的空间,没有数据添0,你可以自己删除两句指令,在debug调试一下,算一下是不是除了指令外给你添加了几句2个字节为0的指令,所有指令的字节总和一定是16的倍数。
这样就是占了48个字节的空间(16进制为30),已知初始cs=0c65,加上48个字节,就是0c68,也就是data的段地址,所以算出stack的段地址=0c69.
至于push ds: 桟空间,就是把ds:和ds:的数据储存在ss:当前sp-2和ss:当前sp-1中.
至于popds:就是把ss:当前sp+2和ss:当前sp+1处储存到ds:和ds:中,并清除栈中的数据,但可能会储存一些另外的数据(和本次编程没什么关系)。
注:每个位置都是高位对应高位,低位对应低位。
页: [1]
查看完整版本: 实验5(3)