鱼C论坛

 找回密码
 立即注册
查看: 2323|回复: 11

关于代码段中使用栈的问题?

[复制链接]
发表于 2012-4-13 11:28:50 | 显示全部楼层 |阅读模式
8鱼币
//下面程序实现依次用内存0:0~0:15单元中的内容改写程序中的数据,数据传送用栈来进行。。。//assume cs:code
code segment
  dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
  
  dw 0,0,0,0,0,0,0,0,0,0
  
start: mov ax,cs
         mov ss,ax
                 mov sp,24h
           
                 mov ax,0
                 mov ds,ax
                 mov bx,0
                 mov cx,8
           
s:     push [bx]
       pop cs:[bx]
               add bx,2
               loop s
           
           mov ax,4c00h
           int 21h
           
code ends
end start//    什么意思啊??  看不懂 啊 ....那位鱼友 能细讲一下 啊???????关于入栈和出栈数据在哪存放问题????、、???是怎么替换数据的 》?  本来的0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
这些数据是在哪存放的?栈怎么能替换这些数据?push [bx】入栈是讲0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h这些数据存放在16~35的栈中吗?出栈怎么实现数据的替换呢???????

最佳答案

查看完整内容

我来试着回答下啊: 咱们一句一句来解释啊: assume cs:codesg // 这里就是一句伪指令,就是告知编译器,下面的语句是要在cs这个段中执行,并且起个名字为(codesg),当然了名字尅有随便起,也可以叫abc,或则个def codesg segment // codesg 段的开始 dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h // 表示把这些字型数据分别存放在,以cs为段地址0为偏移地址的当前的段中,因为在程序第一句话就说明了下面的 ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 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 // 进入到下一个循环

下面的就不打了 都是结束语句了

不知道能不能帮到你
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-4-13 12:20:53 | 显示全部楼层
本帖最后由 hxs554f 于 2012-4-13 12:30 编辑

;由于不清楚代码要实现的功能,自能妄加揣测。自认为是将前面内存中的数据放入后面的内存中
assume cs:code
code segment
  dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
  dw 0,0,0,0,0,0,0,0,0,0
                        ;这些数据是存放在代码段的最前面
start: mov ax,cs        
       mov ss,ax         
       mov sp,24h       ;数据放在代码段中,将cs的值传给ss,并设置好sp就可以对数据惊醒入栈出栈操作
           
   ;   mov ax,0
       mov ds,ax        ;ds应该和cs相同吧
       mov bx,0         ;ds:[bx]指向第一个数据
       mov cx,8
           
s:     push [bx]        ;
       pop [bx+10h]     ;将数据放到 dw 0,0,0,0,0,0,0,0,0,0 中
      ;pop cs:[bx]     
       add bx,2
       loop s
           
       mov ax,4c00h
       int 21h
           
code ends
end start
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2012-4-13 12:43:01 | 显示全部楼层

次用内存0:0~0:15单元中的内容改写程序中的数据  什么意思?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2012-4-13 12:47:53 | 显示全部楼层
hxs554f 发表于 2012-4-13 12:20
;由于不清楚代码要实现的功能,自能妄加揣测。自认为是将前面内存中的数据放入后面的内存中
assume cs:co ...

assume cs:code

code segment
      dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
start: mov ax,0
        mov ds,ax
                mov bx,0
               
                mov cx,8
s:      mov ax,[bx]
        mov cs:[bx],ax
                add bx,2
                loop s
               
                mov ax,4c00h
                int 21h
code ends
end
这是第二种做法....
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2012-4-13 12:49:36 | 显示全部楼层
hxs554f 发表于 2012-4-13 12:20
;由于不清楚代码要实现的功能,自能妄加揣测。自认为是将前面内存中的数据放入后面的内存中
assume cs:co ...

我感觉是内存中原有的数据把dw的数据给覆盖
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-4-13 13:14:54 | 显示全部楼层
芊芊 发表于 2012-4-13 12:47
assume cs:code

code segment

哦,是将0:0~0:15中的数据覆盖掉cs段首的数据
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2012-4-13 13:18:05 | 显示全部楼层
hxs554f 发表于 2012-4-13 13:14
哦,是将0:0~0:15中的数据覆盖掉cs段首的数据

恩恩 我是按照dw从0~15 第二个dw16~35   35+1 这样求栈顶的  那默认不是吧程序的数据从内存0开始计算了?  内存中0~15的数据不是程序dw的数据了吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-4-13 13:36:24 | 显示全部楼层
芊芊 发表于 2012-4-13 13:18
恩恩 我是按照dw从0~15 第二个dw16~35   35+1 这样求栈顶的  那默认不是吧程序的数据从内存0开始计算了? ...

你在循环结构中push后面就接着pop,栈顶指针指向的位置实际上没变。
内存0:0中数据并不是dw中的数据,cs:0中才是dw的数据
360截图20120413132600578.jpg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2012-4-13 18:22:12 | 显示全部楼层
梦想与现实 发表于 2012-4-13 11:28
我来试着回答下啊:
咱们一句一句来解释啊:
assume cs:codesg  // 这里就是一句伪指令,就是告 ...

人才啊 这位哥哥~~~求企鹅号~~~{:7_169:}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2012-4-13 18:23:00 | 显示全部楼层
hxs554f 发表于 2012-4-13 13:36
你在循环结构中push后面就接着pop,栈顶指针指向的位置实际上没变。
内存0:0中数据并不是dw中的数据,cs: ...

恩恩  ~~~cs:0中才是dw的数据  我理解错了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2012-4-13 18:38:21 | 显示全部楼层
梦想与现实 发表于 2012-4-13 11:28
我来试着回答下啊:
咱们一句一句来解释啊:
assume cs:codesg  // 这里就是一句伪指令,就是告 ...

QQ截图20120413183857.jpg 是这意思吧  我理解对不
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-8 11:00

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表