比如将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]指令时,会把代码段中指令搞乱了,你应该
另外设置一个数据段
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
http://topic.csdn.net/u/20101026/00/a013de8f-37e4-472a-9e2f-ce49374d95c0.html
#4
MOV AX,1000H
改为:MOV AX,0020H试试。在10020H内存空间处肯定放的是受到系统保护的系统程序,所以说要在一块空的内存空间内写入数据或指令才是安全的,所以我选用0020:0020这段。
改为: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赋值之后就不会破坏程序了。
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 这些单位的值是被存在什么地址的啊?
是不是在你敲完代码之后系统就将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里面的容器,用来装数据。
ss和sp值的设定是连续完成的,防止中断破坏。SP的初值是0,r命令可查看所有寄存器的内容。
AX,BX,CX,DX,CS,IP,SS,SP 这些单位的值是被存在什么地址的啊?——这个问题就像是问:杯子里的水是被存在什么地址啊?答案就是杯子里。这些寄存器说到底就是cpu里面的容器,用来装数据。
#8
程序与数据在内存的位置程序员是清楚的
我们可以将数据和代码放在一个段中
但是程序员必须自己保证这些数据是安全的,不会自己破坏
我们可以将数据和代码放在一个段中
但是程序员必须自己保证这些数据是安全的,不会自己破坏
#9
ADD AX,[2] 的时候不会破坏代码,因为没有修改内存,只是使用了内存的数据
#10
本例中压栈出栈可能会破坏代码
这个要看你代码占内存的长度,在程序执行前科一查看内存,看代码段占用多少内存
所以程序不一定有错,不过最好不要写这种程序,可读性极差,容易出错
汇编的COM文件就是这种只有一个段,用来写磁盘引导程序
这个要看你代码占内存的长度,在程序执行前科一查看内存,看代码段占用多少内存
所以程序不一定有错,不过最好不要写这种程序,可读性极差,容易出错
汇编的COM文件就是这种只有一个段,用来写磁盘引导程序
#11
#12
谢谢!各位大哥!的指教。。
#1
你这里的数据段与代码段一致,那么在运行MOV AX,[0]
ADD AX,[2]指令时,会把代码段中指令搞乱了,你应该
另外设置一个数据段
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
http://topic.csdn.net/u/20101026/00/a013de8f-37e4-472a-9e2f-ce49374d95c0.html
#4
MOV AX,1000H
改为:MOV AX,0020H试试。在10020H内存空间处肯定放的是受到系统保护的系统程序,所以说要在一块空的内存空间内写入数据或指令才是安全的,所以我选用0020:0020这段。
改为: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赋值之后就不会破坏程序了。
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 这些单位的值是被存在什么地址的啊?
是不是在你敲完代码之后系统就将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里面的容器,用来装数据。
ss和sp值的设定是连续完成的,防止中断破坏。SP的初值是0,r命令可查看所有寄存器的内容。
AX,BX,CX,DX,CS,IP,SS,SP 这些单位的值是被存在什么地址的啊?——这个问题就像是问:杯子里的水是被存在什么地址啊?答案就是杯子里。这些寄存器说到底就是cpu里面的容器,用来装数据。
#8
程序与数据在内存的位置程序员是清楚的
我们可以将数据和代码放在一个段中
但是程序员必须自己保证这些数据是安全的,不会自己破坏
我们可以将数据和代码放在一个段中
但是程序员必须自己保证这些数据是安全的,不会自己破坏
#9
ADD AX,[2] 的时候不会破坏代码,因为没有修改内存,只是使用了内存的数据
#10
本例中压栈出栈可能会破坏代码
这个要看你代码占内存的长度,在程序执行前科一查看内存,看代码段占用多少内存
所以程序不一定有错,不过最好不要写这种程序,可读性极差,容易出错
汇编的COM文件就是这种只有一个段,用来写磁盘引导程序
这个要看你代码占内存的长度,在程序执行前科一查看内存,看代码段占用多少内存
所以程序不一定有错,不过最好不要写这种程序,可读性极差,容易出错
汇编的COM文件就是这种只有一个段,用来写磁盘引导程序
#11
#12
谢谢!各位大哥!的指教。。