CS,DS,SS 求解答

时间:2021-11-23 17:04:29
一段内存,可以即是代码的存储空间,又是数据的存储空间,还可以是栈空间,也可以什么不是。关键在于CPU中寄存器的设置,即:CS、IP、SS、DS的指向。
比如将10000H-1001FH按排为代码段,并在里面存储如下代码。
MOV AX,1000H
MOV SS,AX
MOV SP,0020H 
MOV AX,CS
MOV DS,AX
MOV AX,[0]
ADD  AX,[2]
MOV BX,[4]
ADD  BX,[6]
PUSH AX
PUSH BX
POP AX
POP BX  
在执行到ADD AX,[2] 代码段的代段就会被破坏掉!。。 CS、IP、SS、SP、DS哪个地方需要设置。。
书上说,CS IP SS SP  DS 都可以同一段内存中,但我实际运行中CS代码结构会被改变。。 
 

12 个解决方案

#1


你这里的数据段与代码段一致,那么在运行MOV AX,[0]
ADD AX,[2]指令时,会把代码段中指令搞乱了,你应该
另外设置一个数据段

#2


这是为什么呀 mov ax,[0] add ax,[2] 怎么会改变内存里的值呢?

#3


原因找到了可以把sp的值改大点改成40  
http://topic.csdn.net/u/20101026/00/a013de8f-37e4-472a-9e2f-ce49374d95c0.html

#4


MOV AX,1000H
改为:MOV AX,0020H试试。在10020H内存空间处肯定放的是受到系统保护的系统程序,所以说要在一块空的内存空间内写入数据或指令才是安全的,所以我选用0020:0020这段。

#5


这段代码是王爽那本书上的,要想让三个段在同一个段并且程序能够运行,需要改一下程序,你再到机器上在debug下调试,看看过程:
CODE SEGMENT
  ASSUME  CS:CODE,DS:CODE,SS:CODE
START:
  MOV AX,CS;如果这里依然是1000h的话,这个程序运行是没有问题的
  MOV SS,AX
  MOV SP,0020H  
  MOV AX,CS
  MOV DS,AX
  MOV AX,[0]
  ADD AX,[2]
  MOV BX,[4]
  ADD BX,[6]
  PUSH AX
  PUSH BX
  POP AX
  POP BX 
  MOV  AH,4CH
  INT 21H
CODE ENDS
  END START
当程序给SS和SP赋值之后,程序的末尾“MOV AH,4CH  INT 21H”就被破坏:因为这时相当于把堆栈的位置和深度都确定了,并且在栈中存入了“0DFEH”和SS中的堆栈段地址,所占的偏移地址为1CH、1DH、1EH和1FH,而这几个偏移地址对应的内容恰恰就是“MOV AH,4CH  INT 21H”。
   因此,如果把SP增大些,错开程序内容,在对SS和SP赋值之后就不会破坏程序了。

#6


你好! 我在代码执行之前 将 CS:1000 ip:0 ss:1000 sp:20 都预先付值了,为嘛执行还是会出现相同的问题?
是不是在你敲完代码之后系统就将SP设置为默认的地址:FFEE..
对于偏移地址被暂用还是不太理解。。
AX,BX,CX,DX,CS,IP,SS,SP 这些单位的值是被存在什么地址的啊? 

#7


这和cs是多大的值没有关系,关键是ss=cs。你在debug下用u命令反汇编,能看出代码段对应的偏移地址范围是0000——0047H(最左边相同的那列是代码段段地址,冒号后面的是偏移地址),而SP=20H是在这个范围内的,也就是访问堆栈会破坏相应位置的内存内容,而不幸的是这些内容恰恰是程序的代码。
ss和sp值的设定是连续完成的,防止中断破坏。SP的初值是0,r命令可查看所有寄存器的内容。
AX,BX,CX,DX,CS,IP,SS,SP 这些单位的值是被存在什么地址的啊?——这个问题就像是问:杯子里的水是被存在什么地址啊?答案就是杯子里。这些寄存器说到底就是cpu里面的容器,用来装数据。

#8


程序与数据在内存的位置程序员是清楚的

我们可以将数据和代码放在一个段中

但是程序员必须自己保证这些数据是安全的,不会自己破坏

#9


ADD AX,[2] 的时候不会破坏代码,因为没有修改内存,只是使用了内存的数据

#10


本例中压栈出栈可能会破坏代码

这个要看你代码占内存的长度,在程序执行前科一查看内存,看代码段占用多少内存

所以程序不一定有错,不过最好不要写这种程序,可读性极差,容易出错

汇编的COM文件就是这种只有一个段,用来写磁盘引导程序

#11


该回复于2012-09-22 10:38:07被版主删除

#12


谢谢!各位大哥!的指教。。

#1


你这里的数据段与代码段一致,那么在运行MOV AX,[0]
ADD AX,[2]指令时,会把代码段中指令搞乱了,你应该
另外设置一个数据段

#2


这是为什么呀 mov ax,[0] add ax,[2] 怎么会改变内存里的值呢?

#3


原因找到了可以把sp的值改大点改成40  
http://topic.csdn.net/u/20101026/00/a013de8f-37e4-472a-9e2f-ce49374d95c0.html

#4


MOV AX,1000H
改为:MOV AX,0020H试试。在10020H内存空间处肯定放的是受到系统保护的系统程序,所以说要在一块空的内存空间内写入数据或指令才是安全的,所以我选用0020:0020这段。

#5


这段代码是王爽那本书上的,要想让三个段在同一个段并且程序能够运行,需要改一下程序,你再到机器上在debug下调试,看看过程:
CODE SEGMENT
  ASSUME  CS:CODE,DS:CODE,SS:CODE
START:
  MOV AX,CS;如果这里依然是1000h的话,这个程序运行是没有问题的
  MOV SS,AX
  MOV SP,0020H  
  MOV AX,CS
  MOV DS,AX
  MOV AX,[0]
  ADD AX,[2]
  MOV BX,[4]
  ADD BX,[6]
  PUSH AX
  PUSH BX
  POP AX
  POP BX 
  MOV  AH,4CH
  INT 21H
CODE ENDS
  END START
当程序给SS和SP赋值之后,程序的末尾“MOV AH,4CH  INT 21H”就被破坏:因为这时相当于把堆栈的位置和深度都确定了,并且在栈中存入了“0DFEH”和SS中的堆栈段地址,所占的偏移地址为1CH、1DH、1EH和1FH,而这几个偏移地址对应的内容恰恰就是“MOV AH,4CH  INT 21H”。
   因此,如果把SP增大些,错开程序内容,在对SS和SP赋值之后就不会破坏程序了。

#6


你好! 我在代码执行之前 将 CS:1000 ip:0 ss:1000 sp:20 都预先付值了,为嘛执行还是会出现相同的问题?
是不是在你敲完代码之后系统就将SP设置为默认的地址:FFEE..
对于偏移地址被暂用还是不太理解。。
AX,BX,CX,DX,CS,IP,SS,SP 这些单位的值是被存在什么地址的啊? 

#7


这和cs是多大的值没有关系,关键是ss=cs。你在debug下用u命令反汇编,能看出代码段对应的偏移地址范围是0000——0047H(最左边相同的那列是代码段段地址,冒号后面的是偏移地址),而SP=20H是在这个范围内的,也就是访问堆栈会破坏相应位置的内存内容,而不幸的是这些内容恰恰是程序的代码。
ss和sp值的设定是连续完成的,防止中断破坏。SP的初值是0,r命令可查看所有寄存器的内容。
AX,BX,CX,DX,CS,IP,SS,SP 这些单位的值是被存在什么地址的啊?——这个问题就像是问:杯子里的水是被存在什么地址啊?答案就是杯子里。这些寄存器说到底就是cpu里面的容器,用来装数据。

#8


程序与数据在内存的位置程序员是清楚的

我们可以将数据和代码放在一个段中

但是程序员必须自己保证这些数据是安全的,不会自己破坏

#9


ADD AX,[2] 的时候不会破坏代码,因为没有修改内存,只是使用了内存的数据

#10


本例中压栈出栈可能会破坏代码

这个要看你代码占内存的长度,在程序执行前科一查看内存,看代码段占用多少内存

所以程序不一定有错,不过最好不要写这种程序,可读性极差,容易出错

汇编的COM文件就是这种只有一个段,用来写磁盘引导程序

#11


该回复于2012-09-22 10:38:07被版主删除

#12


谢谢!各位大哥!的指教。。