根据上一章的内容,战场数据共630字节大小,并且分成14×45字节,战场数据这块上最多只能存下45个人物的数据,但英杰传的人物远远不止45个,实际上在BAKDATA.R3中一共保存了384个人物的初始数据(包括以兵种命名的部队或只在剧情中才出现的人物),也就是说在DS段还有一块能保存384个人物数据的内存空间,而对于每个人物都对应唯一的人物代码。
并且上一章还粗略分析了每只部队战场数据的各个偏移的含义,偏移+0的就是保存2字节大小的人物代码,换句话说,就是每只部队战场数据偏移+0的人物代码的来源就是人物数据所在内存空间对应人物代码,而这人物代码的分配也是和每只部队战场数据偏移+2的战场代码一样是按照顺序进行分配了,但在人物数据这部分的人物代码并不是从0开始,而是从0x200(512)开始的,而战场数据的那块数据的人物代码确实是从0开始的,也就是说,人物数据的人物代码 = 战场数据的人物代码 + 0x200(512),至于具体的细节后文再解析。
扯远了,本章开头的XYZ对应的值是什么才是本节的重点,Z其实已经透露出来了,就是0x180(384),而对应的人物代码的范围就是0200 - 0379,0200就是劉備,0201是关羽,0204是曹操,0208是吕布,0200 - 02FF一共256个人物都是具体姓名的人物,从0300 - 035F是以兵种命名的部队,而0360 - 0379是这部分人物就很杂乱了,比如道具屋0376,李明0377,总之一共384个。
而XY,还是在汇编中找这类似战场数据中这部分代码的,从而对应人物数据的XY。
seg002:7746 B0 0E mov al, 0Eh
seg002:7748 F6 66 FF mul [bp+var_1] ; 部队战场代码
seg002:774B 05 76 D0 add ax, 0D076h
在代码找到了这两个部分的汇编代码,相似度很高吧,当然只是举出两个例子,arg_0的值还是以0xD076为首项,0xD(14)为公差,0x2D(45)为项数的一个十六进制下的等差数列中的一个地址值,两个部分的汇编代码sub_22F6A和sub_23098这两个函数的具体内容这章也会大致介绍。
seg002:6E7C 8B 76 06 mov si, [bp+arg_0]
seg002:6E7F 8A 44 0C mov al, [si+0Ch]
seg002:6E82 50 push ax
seg002:6E83 6B 04 2C imul ax, [si], 2Ch ; [si]获取战场数据的首地址对应的人物代码,并且乘0x2C(44),并且传给AX
seg002:6E86 05 16 68 add ax, 6816h
seg002:6E89 50 push ax ; 人物数据的首地址
seg002:6E8A 9A 0A 60 F6 1C call sub_22F6A
seg002:6E98 8B 76 06 mov si, [bp+arg_0]
seg002:6E9B 8A 44 0C mov al, [si+0Ch]
seg002:6E9E 50 push ax
seg002:6E9F 6B 04 2C imul ax, [si], 2Ch ; [si]获取战场数据的首地址对应的人物代码,并且乘0x2C(44),并且传给AX
seg002:6EA2 05 16 68 add ax, 6816h
seg002:6EA5 50 push ax ; 人物数据的首地址
seg002:6EA6 9A 38 61 F6 1C call sub_23098
seg002:6E83-seg002:6E86/seg002:6E9F-seg002:6EA2,与seg002:7746-seg002:774B的地址计算方法很相似吧,seg002:6E7F/seg002:6E9B都是获取战场数据的一个方法,可以见上一章回忆一下。
所以X对应的十六进制就是0x6816,Y对应的十六进制就是0x2C,这也是龙吟前辈曾经提到的44字节,对比战场数据的Y为0xE,每一个人物都差了44-14=30(0x2C-0xE)字节大小,Z相差更大,用Y×Z就可以算出人物数据占了多大的内存空间,这两块数据占用的内存大小差距相当大。
总结人物数据的首地址为以0x6816为首项,0x2C(44)为公差,0x180(384)为项数的一个十六进制下的等差数列中的一个地址值。