程序
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:\Users\Administrator>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其只代表这两个段分别和这两个寄存器链接起来了
从其是伪指令也可知道其起不到赋值的作用 毕竟伪指令只是编辑器读取的指令。