程序运行时的ds cs

程序 

assume cs:code,ds:data

data segment

db 'unix'
db 'fork'

data ends

code segment

start: mov al,'a'
mov bl ,'b'
mov ax,4c00h
int 21h

code ends
end start

————————————————————————————————————————————————

debug结果

Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.

C:UsersAdministrator>e:

E:>cd compilation

E:compilation>debug 71.exe
-r
AX=0000 BX=0000 CX=0019 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=140F ES=140F SS=141F CS=1420 IP=0000 NV UP EI PL NZ NA PO NC
1420:0000 B061 MOV AL,61
-

那么如果要查看data中定义的unix和fork怎么看呢?

可以执行debug命令 d 141f:0

结果

141F:0000 75 6E 69 78 66 6F 72 6B-00 00 00 00 00 00 00 00 unixfork........
141F:0010 B0 61 B3 62 B8 00 4C CD-21 00 00 00 00 00 00 00 .a.b..L.!.......
141F:0020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
141F:0030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
141F:0040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
141F:0050 00 00 00 00 00 00 00 00-00 00 00 01 25 04 00 00 ............%...
141F:0060 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
141F:0070 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................

这里就出现问题了ds=140f cs等于1420 好像无论如何都不会出现unix和fork的地址在

141F:0000(开头)吧。

此处的解释是 ds存放着程序所有内存区的段地址

而在每个代码段的开头都有256了字节即0010h的的psp(段前说明程序)

其中代码段和psp在所有内存区中

故程序的起始处应该是所有内存区的短地址即ds的内容加上0010h(跳过psp)

依然存在的疑问 可以看出ds+0010h后和ss的值相同 而不是和想象中的cs相同 cs还要比ss大1 原因至今没懂 未完待解决

5月7日 问老师之后的答案 d 141f:0能查看到data段的数据只是凑巧 不一定每次都是如此 d 141f:0真实的意思是查看程序的开头 而data中的数据

具体分配在哪由系统分配 要查看其内容 可在程序开头加上mov ax,data 再用ax中的内容查看即可

问题基本解决 总结一下ds=140fh 则说明代码的开头为140fh+10h=141fh(与ds差了256个字节 psp的范围) 而这里cs指向了1420 显然和141f之间还有16个字节

这之间的16个字节中前8个字节

存储了data段中的内容 unix fork(但不代表任何情况下的data段的内容一定放在代码段和psp之间)故如mov al,'a'这实际上第一条语句的地址是cs:指向的1420

这里又引出一个问题 为什么明明data中只有8个字节的数据 但他占了16个字节的位置 也不能说占了16个字节 毕竟只是用了前8个字节的位置 后8个字节都是0

-d 141f:0
141F:0000 75 6E 69 78 66 6F 72 6B-00 00 00 00 00 00 00 00 unixfork........//看这一快 前8个字节放着unixfork 后8个字节全是0
141F:0010 B0 61 B3 62 B8 00 4C CD-21 09 5F 83 C4 04 FF 76 .a.b..L.!._....v
141F:0020 04 FF 36 24 21 E8 BC 44-83 C4 04 80 3E 60 08 00 ..6$!..D....>`..
141F:0030 74 3A 8B 9E 72 FF 8B 36-D2 25 8A 00 88 86 70 FF t:..r..6.%....p.
141F:0040 0A C0 74 28 C4 5E 06 26-83 7F 06 00 74 1E A1 A4 ..t(.^.&....t...
141F:0050 07 39 86 72 FF 77 15 8A-86 70 FF 2A E4 50 B8 FD .9.r.w...p.*.P..
141F:0060 05 50 FF 36 24 21 E8 77-63 83 C4 06 FF 36 24 21 .P.6$!.wc....6$!
141F:0070 B8 0A 00 50 E8 47 5E 83-C4 04 5E 8B E5 5D C3 90 ...P.G^...^..]..
-

此非很重要的东西 但我从语言设计的角度上来思考 只有这样才能区分出 data的段地址和 cs的段地址  毕竟段地址加1就是16个字节 如果mov al,'a'

是延续着unixfork之后放的 那么cs:如何表示呢? 显然不好表示 且其ip还不是默认的0000了 要改成0009 (cs=141f的情况下) 

故我认为 但凡系统把数据段放在psp后面了 就一定会让其占的内存为16字节的倍数 这样实际上有区分data和code段的作用

不知道猜测的对不对

由此题懂得的一些小知识: 程序开头的assume cs:code ,ds:data 并不代表mov cs,code mov ds,data其只代表这两个段分别和这两个寄存器链接起来了 

从其是伪指令也可知道其起不到赋值的作用 毕竟伪指令只是编辑器读取的指令。

原文地址:https://www.cnblogs.com/aloney/p/4482964.html