【原创】list在内存中的存储方式研究
本帖最后由 baitang36 于 2020-9-18 16:04 编辑试验程序源码:
(DEFUN TT()
(setq Group1 (list 4294967295 88888888"ABC" 3.1415926535897932384626433832795028841971 ))
(SETQ A "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
(setq Group2 (cons A Group1))
)
编译后解码:
Offset 01234567 89ABCDEF
00000000 0D 0A 20 46 41 53 34 2D46 49 4C 45 20 3B 20 44 FAS4-FILE ; D
00000010 6F 20 6E 6F 74 20 63 6861 6E 67 65 20 69 74 21 o not change it!
00000020 0D 0A 34 39 0D 0A 31 3020 24 14 00 00 00 00 09 4910 $
00000030 09 00 33 38 56 4C 05 0908 00 09 07 00 35 04 06 38VL 5
00000040 00 03 06 05 00 09 04 0006 03 00 03 03 00 03 05
00000050 00 35 02 02 00 03 0B 0601 00 16 24 0D 0A 32 30 5 $20
00000060 39 20 34 20 24 14 01 0101 00 32 00 32 18 2A 39 9 4 $ 2 2 *9
00000070 01 00 5B 54 54 00 00 0101 43 00 00 03 00 0A 32 [TT C 2
00000080 00 32 31 2A 39 01 00 5B47 52 4F 55 50 32 00 43 21*9[GROUP2 C
00000090 4F 4E 53 00 41 00 00 5501 00 34 00 41 41 41 41 ONS AU4 AAAA
000000A0 41 41 41 41 41 41 41 4141 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000000B0 41 41 41 41 41 41 41 4141 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000000C0 41 41 41 41 41 41 41 4141 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000000D0 5B 47 52 4F 55 50 31 004C 49 53 54 00 00 3B 33 [GROUP1 LIST;3
000000E0 2E 31 34 31 35 39 32 3635 33 35 39 00 55 01 00 .14159265359 U
000000F0 03 00 41 42 43 3B 34 3239 34 39 36 37 32 39 35 ABC;4294967295
00000100 2E 30 00 5C 00 00 43 0000 0A 00 0A 5C 00 00 32 .0 \C \2
00000110 00 5B 54 54 00 00 3A 0143 03 00 01 00 1C 14 01 [TT: C
00000120 00 00 00 09 02 00 0A 5700 00 00 00 09 03 00 06 W
00000130 01 00 09 01 00 16 18 008E AC 96 6F 83 6F 56 2A 幀杘僶V*
00000140 0A 3B 66 61 73 34 20 6372 75 6E 63 68 0A 3B 24 ;fas4 crunch ;$
00000150 3B 41 39 2F 31 38 2F 3230 ;A9/18/20
可以看到9个字符串。
09 / 4294967295.0
08 / "ABC"
07 / 3.14159265359
06 / LIST
05 / GROUP1
04 / "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
03 / A
02 / CONS
01 / GROUP2
加载运行一下
命令: (tt)
("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 4.29497e+009 88888888
"ABC" 3.14159)
在内存中可以找到程序代码和变量地址
变量地址:
38 CF AD 13 ;函数地址表
F8 D2 B2 13 ;GROUP2
38 22 6D 0E ;CONS
C0 54 6F 0E ;A
D8 29 B4 13 ;"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
E0 D2 B2 13 ;GROUP1
08 3B 6D 0E ;LIST
C8 52 9F 11;3.14159265359
F8 29 B4 13;"ABC"
D8 52 9F 11;4294967295.0
程序代码如下:
14 00 00 00 00;函数开头
09 09 00 33 38 56 4C 05 09 08 00 09 07 00 35 04 06 00 03 06 05 00
;(setq Group1 (list 4294967295 88888888"ABC" 3.1415926535897932384626433832795028841971 ))
09 04 00 06 03 00 ;(SETQ A "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
03 03 00 03 05 00 35 02 02 00 03 0B 06 01 00 ;(setq Group2 (cons A Group1))
16 ;结束
GROUP1的存放地址是 13B2D2E0
看一下这个地址有什么
13B2D2E0: 84 2E 4F 0E 00 00 00 00 04 00 B2 13 B8 B9 AD 13 08 77 B4 13 00 00 00 00
分行看一下
84 2E 4F 0E ;symbol mark
00 00 00 00 ;
04 00 B2 13 ;未知
B8 B9 AD 13 ;地址
08 77 B4 13 ;存放名称
00 00 00 00 ;
再看一下地址13adb9b8
13ADB9B8: D0 0C 4F 0E 00 00 00 00 D8 52 9F 11 A8 B9 AD 13
D0 0C 4F 0E;cons mark
00 00 00 00;
D8 52 9F 11;
A8 B9 AD 13;下一个cons地址
地址119f52d8的内容
119f52d8: 04 4D 4F 0E 00 00 00 00 00 00 E0 FF FF FF EF 41
04 4D 4F 0E;lnode mark
00 00 00 00
00 00 E0 FF FF FF EF 41;浮点数 4294967295.0
研究了一下,41EFFFFFFFE00000就是浮点数 4294967295.0的16进制编码
13ADB9A8:D0 0C 4F 0E 00 00 00 00 71 AC 98 0A 98 B9 AD 13 ;8888888
D0 0C 4F 0E ;cons mark
00 00 00 00
71 AC 98 0A ;8888888
98 B9 AD 13 ;下一个cons地址
0x0A98AC71=177777777
(177777777-1)/2=88888888
13ADB998: D0 0C 4F 0E 00 00 00 00 F8 29 B4 13 88 B9 AD 13 ;"ABC"
13B429F8: B0 56 4F 0E 00 00 00 00 9E FF C0 13 06 00 00 00 ;"ABC"
B0 56 4F 0E ;lnode mark
00 00 00 00
9E FF C0 13 ;字符串地址
06 00 00 00 ;长度*2
13ADB988: D0 0C 4F 0E 00 00 00 00 C8 52 9F 11 00 00 00 00 ;3.14159265359
注意这里的结尾是00 00 00 00,而不是下一个cons的地址了,这说明是最后一个cons
119F52C8: 04 4D 4F 0E 00 00 00 00 EA 2E 44 54 FB 21 09 40
04 4D 4F 0E ;lnode mark
00 00 00 00
EA 2E 44 54 FB 21 09 40
;400921FB54442EEA 表示浮点数3.14159265359
GROUP2的地址是13b2d2f8
13b2d2f8: 84 2E 4F 0E 00 00 00 00 04 00 B2 13 C8 B9 AD 13 18 77 B4 13 00 00 00 00
84 2E 4F 0E ;symbol mark
00 00 00 00 ;0
04 00 B2 13 ;未知
C8 B9 AD 13 ;地址
18 77 B4 13 ;名称 GROUP2
00 00 00 00 ;0
13adb9c8: D0 0C 4F 0E 00 00 00 00 D8 29 B4 13 B8 B9 AD 13
D0 0C 4F 0E ;cons mark
00 00 00 00 ;0
D8 29 B4 13 ;
B8 B9 AD 13 ;下一个地址
13b429d8:B0 56 4F 0E 00 00 00 00 69 FF C0 13 68 00 00 00
B0 56 4F 0E ;lnode mark
00 00 00 00
69 FF C0 13 ;字符串地址
68 00 00 00 ;长度*2
13c0ff69: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 00
这是变量A那一长串AAAAAAAAAAAAAAAAAAAAAA
13adb9b8: D0 0C 4F 0E 00 00 00 00 D8 52 9F 11 A8 B9 AD 13
这里与GROUP1的cons是相同的地址,后面的也是GROUP1的内容了。
就是说直接利用了GROUP1,没有使用新的内存,是非常节省的。
结论,
整数在内存中直接存储,表示方法是2n+1,88888888在内存中是177777777,也就是0x0A98AC71
浮点数直接编码成16进制数值,400921FB54442EEA 表示浮点数3.14159265359
小数点后位数很多时被截去,精度有一定限制。
大整数直接被编译成了浮点数。41EFFFFFFFE00000就是浮点数 4294967295.0的16进制编码。
list在内存的表示方法:开头是一个symbol表,占用24个字节。
symbol格式如下:
84 2E 4F 0E ;symbol mark
00 00 00 00 ;0
04 00 B2 13 ;未知
C8 B9 AD 13 ;存放内容,cons的开始地址
18 77 B4 13 ;存放名称 GROUP2
00 00 00 00 ;0
里面有list的名称,有cons的开始地址。
list的内容是用多个cons表示的,它组成一个链表。
cons的格式如下:
D0 0C 4F 0E ;cons mark
00 00 00 00 ;0
D8 29 B4 13 ;内容
B8 B9 AD 13 ;下一个地址
每个cons占用16个字节,开始是cons mark,后面跟着一个0或2,意思暂未知,再后面是内容。
内容有的用lnode存储,也有的用cons存储。
最后四个字节是下一个cons的地址。
最后一个cons没有下一个地址,用00 00 00 00表示这个链表结束。
:D:D:D:o:lol 牛逼死了...... 潜入内部看本质。太强悍了吧。 会不会被别有用心之人利用? 正能量的一诺 发表于 2023-2-24 08:54
会不会被别有用心之人利用?
能怎么用?自己做一个acad?
页:
[1]