本帖最后由 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 0 1 2 3 4 5 6 7 8 9 A B C D E F
00000000 0D 0A 20 46 41 53 34 2D 46 49 4C 45 20 3B 20 44 FAS4-FILE ; D
00000010 6F 20 6E 6F 74 20 63 68 61 6E 67 65 20 69 74 21 o not change it!
00000020 0D 0A 34 39 0D 0A 31 30 20 24 14 00 00 00 00 09 49 10 $
00000030 09 00 33 38 56 4C 05 09 08 00 09 07 00 35 04 06 38VL 5
00000040 00 03 06 05 00 09 04 00 06 03 00 03 03 00 03 05
00000050 00 35 02 02 00 03 0B 06 01 00 16 24 0D 0A 32 30 5 $ 20
00000060 39 20 34 20 24 14 01 01 01 00 32 00 32 18 2A 39 9 4 $ 2 2 *9
00000070 01 00 5B 54 54 00 00 01 01 43 00 00 03 00 0A 32 [TT C 2
00000080 00 32 31 2A 39 01 00 5B 47 52 4F 55 50 32 00 43 21*9 [GROUP2 C
00000090 4F 4E 53 00 41 00 00 55 01 00 34 00 41 41 41 41 ONS A U 4 AAAA
000000A0 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000000B0 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000000C0 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000000D0 5B 47 52 4F 55 50 31 00 4C 49 53 54 00 00 3B 33 [GROUP1 LIST ;3
000000E0 2E 31 34 31 35 39 32 36 35 33 35 39 00 55 01 00 .14159265359 U
000000F0 03 00 41 42 43 3B 34 32 39 34 39 36 37 32 39 35 ABC;4294967295
00000100 2E 30 00 5C 00 00 43 00 00 0A 00 0A 5C 00 00 32 .0 \ C \ 2
00000110 00 5B 54 54 00 00 3A 01 43 03 00 01 00 1C 14 01 [TT : C
00000120 00 00 00 09 02 00 0A 57 00 00 00 00 09 03 00 06 W
00000130 01 00 09 01 00 16 18 00 8E AC 96 6F 83 6F 56 2A 幀杘僶V*
00000140 0A 3B 66 61 73 34 20 63 72 75 6E 63 68 0A 3B 24 ;fas4 crunch ;$
00000150 3B 41 39 2F 31 38 2F 32 30 ;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表示这个链表结束。
|