遒羽 发表于 2013-1-29 10:49:37

一直想不通偏移地址怎么算出来的?请教

下面的程序实现依次用内存0:0~0:15单元中的内容改写程序中的数据,数据的传送用栈来进行。栈空间设置在程序内。完成程序:
assume cs:codesg

codesg segment

      dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h

      dw 0,0,0,0,0,0,0,0,0,0

start:mov ax, codesg ;或mov ax, cs

      mov ss,ax

      mov sp, 24h    ;或mov sp, 36   ;(第一版填1ah或26)

      mov ax,0

      mov ds,ax

      mov bx,0

      mov cx,8

    s:push

         pop cs:   ;或 pop ss:

      add bx,2

      loop s

      mov ax,4c00h

      int 21h

codesg ends

end start问题1, mov ax, codesg ;或mov ax, cs 怎么理解??
问题2,mov sp, 24h ;或mov sp, 36 ;(第一版填1ah或26)中,24h想不通。

メ㊣逆ご帅☆ 发表于 2013-1-29 10:49:38

遒羽 发表于 2013-1-29 12:38 static/image/common/back.gif
说得很周到,还遗有疑问:
1,代码中可以写在一行上吗:
2,按照题目,“实现依次用内存0:0~0:15单元中 ...

1.可以
2.
0:0~15单元 指的是段地址为0,偏移为0的地址
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
dw 0,0,0,0,0,0,0,0,0,0
这两个都是CS段中的,不是0:0-0:15的那段内存,完全没关系
还有你说的那个不能叫溢出,应该叫不符合题目要求

メ㊣逆ご帅☆ 发表于 2013-1-29 11:31:05

本帖最后由 メ㊣逆ご帅☆ 于 2013-1-29 12:09 编辑

问题1:mov ax, codesg ;或mov ax, cs
cs:codesg
这句把CS和codesg挂钩也就是说CS寄存器的值=codesg的地址
至于具体CS值为多少,这是不确定的,反正那段地址是安全的
所以,mov ax,codesg等于与mov ax,cs
理由:mov ax,codesg中,codesg就是codesg segment的首地址,cs的值同样也是
问题2:mov sp, 24h ;或mov sp, 36
其实SP栈顶指针代表的就是这个栈的大小
栈需要大点,不然push一次SP栈顶指针需要减2
如果栈顶SP=0,再减2,就会变成FFFE
这样会出问题的。
所以栈要够我们push
也就是说大点没关系,不要太大不然浪费(太大不知道会不会出问题。)



对了差点无视你的标题
偏移地址是把
具体看代码注释

assume cs:codesg

codesg segment
;因为地址是难以确定的,
;偏移一般是靠寄存器动态计算的
;我们这里地址都用假设的
;;假设这里地址为1234H,作为首地址
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h;占16个字节
dw 0,0,0,0,0,0,0,0,0,0 ;占20个字节
;上面一共占36个字节,十六进制是24H

start: mov ax, codesg ;前面一共占24H个字节,所以mov ax,codesg距离首地址24H,所以偏移是24H
;所以地址这样表示1234H:24H

mov ss,ax;mov ax,codesg占3个字节,也就是说mov ss,ax距离我们首地址24H+3个字节
;所以偏移地址是27H,那么地址就是这样表示1234H:27H

mov sp, 24h ;mov ss,ax占2个字节,也就是说mov ss,ax距离我们首地址27H+2个字节
;所以偏移地址是29H,那么地址就是这样表示1234H:29H
mov ax,0 ;mov sp, 24h 占3个字节,也就是说mov ss,ax距离我们首地址29H+3个字节
;所以偏移地址是2CH,那么地址就是这样表示1234H:2CH

mov ds,ax
;以此类推了

mov bx,0

mov cx,8

s: push

pop cs: ;或 pop ss:

add bx,2

loop s

mov ax,4c00h

int 21h

codesg ends

end start

至于如果看一个指令占多少个字节
我是用DEBUG用-u指令查看

如果可以看到mov ax,18BA的机器码是B8BA18
B8一个字节 BA一个 18一个
一共三个
所以mov ax,18BA占三个字节
下面 mov ss,ax
8E一个 D0一个
所以mov ss,ax占2个字节


遒羽 发表于 2013-1-29 12:38:44

メ㊣逆ご帅☆ 发表于 2013-1-29 11:31 static/image/common/back.gif
问题1:mov ax, codesg ;或mov ax, cs
cs:codesg
这句把CS和codesg挂钩也就是说CS寄存器的值=codesg的地 ...

说得很周到,还遗有疑问:
1,代码中dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
dw 0,0,0,0,0,0,0,0,0,0可以写在一行上吗:
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h,0,0,0,0,0,0,0,0,0,02,按照题目,“实现依次用内存0:0~0:15单元中的内容改写程序中的数据 ”,程序中数据有36字节,内存只有16个单元16个字节,不是溢出了吗?谢谢!

NGtailang 发表于 2013-1-29 22:32:19

好多神人啊,努力学习去

shansongh 发表于 2013-1-29 23:11:03

RE: 一直想不通偏移地址怎么算出来的?请教

遒羽 发表于 2013-1-29 12:38 static/image/common/back.gif
说得很周到,还遗有疑问:
1,代码中可以写在一行上吗:
2,按照题目,“实现依次用内存0:0~0:15单元中 ...

1.在理论上是可以的,所谓的栈段是人们对这段内存强加的理解,cpu只会对ss ip有反应
所以理论上可行,重点是如果让别人读代码的时候就会莫名其妙了!!!!
2.题目的意思是让我们达到将0:0到0:15的数据覆盖程序第一个dw中的16个字节的内容,所以不会溢出

遒羽 发表于 2013-1-30 09:05:17

shansongh 发表于 2013-1-29 23:11 static/image/common/back.gif
1.在理论上是可以的,所谓的栈段是人们对这段内存强加的理解,cpu只会对ss ip有反应
所以理论上可行,重 ...

谢谢shansongh!

颂歌 发表于 2013-3-3 12:43:37

好东西,顶一
页: [1]
查看完整版本: 一直想不通偏移地址怎么算出来的?请教