|
发表于 2012-4-13 11:28:51
|
显示全部楼层
我来试着回答下啊:
咱们一句一句来解释啊:
assume cs:codesg // 这里就是一句伪指令,就是告知编译器,下面的语句是要在cs这个段中执行,并且起个名字为(codesg),当然了名字尅有随便起,也可以叫abc,或则个def
codesg segment // codesg 段的开始
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h // 表示把这些字型数据分别存放在,以cs为段地址0为偏移地址的当前的段中,因为在程序第一句话就说明了下面的语句将要在cs段中执行!dw是定义字型的意思,define(定义) word(字型),dw写在前面就表明了它后面的数据是字型数据
dw 0,0,0,0,0,0,0,0,0,0 // 这里是在上一句话结束后,紧跟着后面预留出来的一段20个字节的空间准备作为栈来使用,先预留出来
start: //源程序入口
mov ax,cs
mov ss,ax // 这两句是利用ax作为中介,把cs这个段地址赋值给ss,ss是栈段的段地址,也就是说下面的栈操作就要在cs段中执行了,好,先不要疑问,请往下面看
mov sp,24h // 这里是给栈段的偏移地址赋值为24h,因为程序开始的时候已经在cs段中写入了8个字型数据(一个字型数据等于2个字节),而且下面有预留了10个字形数据,这样我们不难算数一共是8*2+10*2=36 ,所以最后一个字节的地址是cs:35(因为我们存储数据是从0开始的所以最后一个字节的地址是35而不是36),也就是dw 0,0,0,0,0.... 的最后一个0的地址,因为1个字形数据存放的方式是高低字节的方式,所以最后一个地址是高字节位,由于现在这个栈暂时为空,栈顶所指向的位置就应该是最后一个字节的再下一位,所以就指向35后面的再下一位36,注意36是10进制的,这里我们可以转换为24H 这个16进制来进行编程
mov ax,0
mov ds,ax // 再次通过ax赋值给代码段ds段地址,因为题目中提出,内存0:0~0:15单元中的内容,也就是计算机内存中以ds为代码然后以0~15为偏移地址之间的这16个字节的数据,所谓的改写程序中的数据的意思就是用ds数据段中这16个字节的内容,改变我们程序最开始,在cs段中写入的
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h 这段数据
mov bx,0 // 设置bx值为0
mov cx,8 //设置循环次数为8
s: // 定义循环标记
push[bx] // 因为如果以bx为偏移地址的话,就是默认了以ds为段地址,这句话的意思就是将以ds为段地址,bx的值0为偏移地址的数据,压栈到以ss(在前面我们已经设置了csj就是ss的段地址)为段地址,sp(24H)为偏移地址的地方去,总体说就是 ds:0的数据压栈道ss:24h中去,也就是压到了
dw 0,0,0,0,0,0,0,0,0,0 的最后一个0这个地方去
pop cs:[bx] // 好,上面我们已经把内存中的一个字的数据压到了栈中,现在我们要出栈了,出到哪里呢,当然依照题目的意思,我们要用栈中现在这个数据去改变程序最开始
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
的值, pop出栈到,以cs为段地址,bx的值0为偏移地址的地方,也就是0123h这个地方,这样就实现了内存中的数据区改变程序中的数据的
add bx,2 // 这里不用说了,bx增加2,因为一个字型数据等于2个字节,没执行一个覆盖数据就等于一定了2个字节的地址
loop s // 进入到下一个循环
下面的就不打了 都是结束语句了
不知道能不能帮到你
|
|