7. 言語基礎(1)— コンパイル結果のアセンブリを読む

7.1. この章で学ぶこと

  • 前章リスト-1(language_basics_minimal.mojo)のコンパイル結果が、スタック上で何をしているか

  • 定数畳み込み、List 構築、文字列オブジェクト、引数テーブル、後片付けパターンの流れ

前章では、言語基礎の最小サンプル(リスト-1)を示しました。 この章では、そのコンパイル結果(リスト-2)を手がかりに、main() の機械語を段階的に追います。

このコードをコンパイルすると、実際には機械語へ変換されます。


language_basics_minimal.o:	file format elf64-x86-64

Disassembly of section .text:

0000000000000000 <language_basics_minimal::main()>:
; def main():
       0: 48 81 ec 08 03 00 00         	subq	$776, %rsp              # imm = 0x308
;     var n: Int = 42
       7: 48 c7 84 24 e8 00 00 00 2a 00 00 00  	movq	$42, 232(%rsp)
;     var doubled = n * 2
      13: 48 c7 84 24 f0 00 00 00 54 00 00 00  	movq	$84, 240(%rsp)
;     var xs: List[Int] = [1, 2, 3]
      1f: 48 c7 84 24 10 01 00 00 01 00 00 00  	movq	$1, 272(%rsp)
      2b: 48 c7 84 24 18 01 00 00 02 00 00 00  	movq	$2, 280(%rsp)
      37: 48 c7 84 24 20 01 00 00 03 00 00 00  	movq	$3, 288(%rsp)
      43: 48 8d 84 24 10 01 00 00      	leaq	272(%rsp), %rax
      4b: 48 89 84 24 28 01 00 00      	movq	%rax, 296(%rsp)
      53: 48 8d 84 24 18 01 00 00      	leaq	280(%rsp), %rax
      5b: 48 89 84 24 30 01 00 00      	movq	%rax, 304(%rsp)
      63: 48 8d 84 24 20 01 00 00      	leaq	288(%rsp), %rax
      6b: 48 89 84 24 38 01 00 00      	movq	%rax, 312(%rsp)
      73: be 03 00 00 00               	movl	$3, %esi
      78: 48 8d bc 24 28 01 00 00      	leaq	296(%rsp), %rdi
      80: 90                           	nop
      81: 48 89 bc 24 b8 02 00 00      	movq	%rdi, 696(%rsp)
      89: 48 c7 84 24 c0 02 00 00 03 00 00 00  	movq	$3, 704(%rsp)
      95: 90                           	nop
      96: 48 89 bc 24 c8 02 00 00      	movq	%rdi, 712(%rsp)
      9e: 48 c7 84 24 d0 02 00 00 03 00 00 00  	movq	$3, 720(%rsp)
      aa: 48 8d 94 24 f8 00 00 00      	leaq	248(%rsp), %rdx
      b2: e8 00 00 00 00               	callq	0xb7 <language_basics_minimal::main()+0xb7>
;     var xs: List[Int] = [1, 2, 3]
      b7: 48 8d bc 24 47 01 00 00      	leaq	327(%rsp), %rdi
      bf: e8 00 00 00 00               	callq	0xc4 <language_basics_minimal::main()+0xc4>
;     var label = String("count")
      c4: 48 c7 84 24 50 01 00 00 05 00 00 00  	movq	$5, 336(%rsp)
      d0: 48 8d 84 24 48 01 00 00      	leaq	328(%rsp), %rax
      d8: 48 89 84 24 90 00 00 00      	movq	%rax, 144(%rsp)
      e0: 48 8d 05 00 00 00 00         	leaq	(%rip), %rax            # 0xe7 <language_basics_minimal::main()+0xe7>
      e7: 48 89 84 24 60 01 00 00      	movq	%rax, 352(%rsp)
      ef: 48 8d 05 00 00 00 00         	leaq	(%rip), %rax            # 0xf6 <language_basics_minimal::main()+0xf6>
      f6: 48 89 84 24 68 01 00 00      	movq	%rax, 360(%rsp)
      fe: 48 8d 05 00 00 00 00         	leaq	(%rip), %rax            # 0x105 <language_basics_minimal::main()+0x105>
     105: 48 89 84 24 48 01 00 00      	movq	%rax, 328(%rsp)
     10d: 48 8d 84 24 48 01 00 00      	leaq	328(%rsp), %rax
     115: 48 83 c0 10                  	addq	$16, %rax
     119: 48 89 84 24 98 00 00 00      	movq	%rax, 152(%rsp)
     121: 48 b8 00 00 00 00 00 00 00 20	movabsq	$2305843009213693952, %rax # imm = 0x2000000000000000
     12b: 48 89 84 24 58 01 00 00      	movq	%rax, 344(%rsp)
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     133: 48 c7 84 24 78 01 00 00 02 00 00 00  	movq	$2, 376(%rsp)
     13f: 48 8d 84 24 70 01 00 00      	leaq	368(%rsp), %rax
     147: 48 89 84 24 a0 00 00 00      	movq	%rax, 160(%rsp)
     14f: 48 8d 05 00 00 00 00         	leaq	(%rip), %rax            # 0x156 <language_basics_minimal::main()+0x156>
     156: 48 89 84 24 88 01 00 00      	movq	%rax, 392(%rsp)
     15e: 48 8d 05 00 00 00 00         	leaq	(%rip), %rax            # 0x165 <language_basics_minimal::main()+0x165>
     165: 48 89 84 24 90 01 00 00      	movq	%rax, 400(%rsp)
     16d: 48 8d 05 00 00 00 00         	leaq	(%rip), %rax            # 0x174 <language_basics_minimal::main()+0x174>
     174: 48 89 84 24 70 01 00 00      	movq	%rax, 368(%rsp)
     17c: 48 b8 00 00 00 00 00 00 00 20	movabsq	$2305843009213693952, %rax # imm = 0x2000000000000000
     186: 48 89 84 24 80 01 00 00      	movq	%rax, 384(%rsp)
     18e: 48 c7 84 24 a0 01 00 00 05 00 00 00  	movq	$5, 416(%rsp)
     19a: 48 8d 84 24 98 01 00 00      	leaq	408(%rsp), %rax
     1a2: 48 89 84 24 a8 00 00 00      	movq	%rax, 168(%rsp)
     1aa: 48 8d 05 00 00 00 00         	leaq	(%rip), %rax            # 0x1b1 <language_basics_minimal::main()+0x1b1>
     1b1: 48 89 84 24 b0 01 00 00      	movq	%rax, 432(%rsp)
     1b9: 48 8d 05 00 00 00 00         	leaq	(%rip), %rax            # 0x1c0 <language_basics_minimal::main()+0x1c0>
     1c0: 48 89 84 24 b8 01 00 00      	movq	%rax, 440(%rsp)
     1c8: 48 8d 05 00 00 00 00         	leaq	(%rip), %rax            # 0x1cf <language_basics_minimal::main()+0x1cf>
     1cf: 48 89 84 24 98 01 00 00      	movq	%rax, 408(%rsp)
     1d7: 48 8d 84 24 98 01 00 00      	leaq	408(%rsp), %rax
     1df: 48 83 c0 10                  	addq	$16, %rax
     1e3: 48 89 84 24 b0 00 00 00      	movq	%rax, 176(%rsp)
     1eb: 48 b8 00 00 00 00 00 00 00 20	movabsq	$2305843009213693952, %rax # imm = 0x2000000000000000
     1f5: 48 89 84 24 a8 01 00 00      	movq	%rax, 424(%rsp)
     1fd: 48 c7 84 24 c8 01 00 00 01 00 00 00  	movq	$1, 456(%rsp)
     209: 48 8d 84 24 c0 01 00 00      	leaq	448(%rsp), %rax
     211: 48 89 84 24 b8 00 00 00      	movq	%rax, 184(%rsp)
     219: 48 8d 05 00 00 00 00         	leaq	(%rip), %rax            # 0x220 <language_basics_minimal::main()+0x220>
     220: 48 89 84 24 d8 01 00 00      	movq	%rax, 472(%rsp)
     228: 48 8d 05 00 00 00 00         	leaq	(%rip), %rax            # 0x22f <language_basics_minimal::main()+0x22f>
     22f: 48 89 84 24 e0 01 00 00      	movq	%rax, 480(%rsp)
     237: 48 8d 05 00 00 00 00         	leaq	(%rip), %rax            # 0x23e <language_basics_minimal::main()+0x23e>
     23e: 48 89 84 24 c0 01 00 00      	movq	%rax, 448(%rsp)
     246: 48 8d 84 24 c0 01 00 00      	leaq	448(%rsp), %rax
     24e: 48 83 c0 10                  	addq	$16, %rax
     252: 48 89 84 24 c0 00 00 00      	movq	%rax, 192(%rsp)
     25a: 48 b8 00 00 00 00 00 00 00 20	movabsq	$2305843009213693952, %rax # imm = 0x2000000000000000
     264: 48 89 84 24 d0 01 00 00      	movq	%rax, 464(%rsp)
     26c: 48 c7 84 24 f0 01 00 00 01 00 00 00  	movq	$1, 496(%rsp)
     278: 48 8d 84 24 e8 01 00 00      	leaq	488(%rsp), %rax
     280: 48 89 84 24 c8 00 00 00      	movq	%rax, 200(%rsp)
     288: 48 8d 05 00 00 00 00         	leaq	(%rip), %rax            # 0x28f <language_basics_minimal::main()+0x28f>
     28f: 48 89 84 24 00 02 00 00      	movq	%rax, 512(%rsp)
     297: 48 8d 05 00 00 00 00         	leaq	(%rip), %rax            # 0x29e <language_basics_minimal::main()+0x29e>
     29e: 48 89 84 24 08 02 00 00      	movq	%rax, 520(%rsp)
     2a6: 48 8d 05 00 00 00 00         	leaq	(%rip), %rax            # 0x2ad <language_basics_minimal::main()+0x2ad>
     2ad: 48 89 84 24 e8 01 00 00      	movq	%rax, 488(%rsp)
     2b5: 48 8d 84 24 e8 01 00 00      	leaq	488(%rsp), %rax
     2bd: 48 83 c0 10                  	addq	$16, %rax
     2c1: 48 89 84 24 d0 00 00 00      	movq	%rax, 208(%rsp)
     2c9: 48 b8 00 00 00 00 00 00 00 20	movabsq	$2305843009213693952, %rax # imm = 0x2000000000000000
     2d3: 48 89 84 24 f8 01 00 00      	movq	%rax, 504(%rsp)
     2db: 90                           	nop
     2dc: 48 8b 84 24 00 01 00 00      	movq	256(%rsp), %rax
     2e4: 48 89 84 24 d8 00 00 00      	movq	%rax, 216(%rsp)
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     2ec: 48 8d bc 24 f8 00 00 00      	leaq	248(%rsp), %rdi
     2f4: e8 00 00 00 00               	callq	0x2f9 <language_basics_minimal::main()+0x2f9>
     2f9: 48 8b 94 24 d8 00 00 00      	movq	216(%rsp), %rdx
     301: 48 89 94 24 10 02 00 00      	movq	%rdx, 528(%rsp)
     309: 48 8b b4 24 e8 00 00 00      	movq	232(%rsp), %rsi
     311: 48 8b 8c 24 f0 00 00 00      	movq	240(%rsp), %rcx
     319: 48 8d 3d 00 00 00 00         	leaq	(%rip), %rdi            # 0x320 <language_basics_minimal::main()+0x320>
     320: 48 89 e0                     	movq	%rsp, %rax
     323: 48 89 84 24 e0 00 00 00      	movq	%rax, 224(%rsp)
     32b: 48 89 78 20                  	movq	%rdi, 32(%rax)
     32f: 48 8d 3d 00 00 00 00         	leaq	(%rip), %rdi            # 0x336 <language_basics_minimal::main()+0x336>
     336: 48 89 78 10                  	movq	%rdi, 16(%rax)
     33a: 48 89 50 08                  	movq	%rdx, 8(%rax)
     33e: 48 8d 94 24 e8 01 00 00      	leaq	488(%rsp), %rdx
     346: 48 89 10                     	movq	%rdx, (%rax)
     349: 48 c7 40 38 01 00 00 00      	movq	$1, 56(%rax)
     351: c7 40 30 00 00 00 00         	movl	$0, 48(%rax)
     358: 48 c7 40 28 01 00 00 00      	movq	$1, 40(%rax)
     360: 48 c7 40 18 01 00 00 00      	movq	$1, 24(%rax)
     368: 48 8d bc 24 70 01 00 00      	leaq	368(%rsp), %rdi
     370: 48 8d 94 24 98 01 00 00      	leaq	408(%rsp), %rdx
     378: 4c 8d 84 24 c0 01 00 00      	leaq	448(%rsp), %r8
     380: 4c 8d 8c 24 48 01 00 00      	leaq	328(%rsp), %r9
     388: e8 00 00 00 00               	callq	0x38d <language_basics_minimal::main()+0x38d>
     38d: 48 b8 00 00 00 00 00 00 00 40	movabsq	$4611686018427387904, %rax # imm = 0x4000000000000000
     397: 48 23 84 24 80 01 00 00      	andq	384(%rsp), %rax
     39f: 48 83 f8 00                  	cmpq	$0, %rax
     3a3: 0f 84 b2 00 00 00            	je	0x45b <language_basics_minimal::main()+0x45b>
     3a9: 48 8b 84 24 a0 00 00 00      	movq	160(%rsp), %rax
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     3b1: 48 8b 00                     	movq	(%rax), %rax
     3b4: 90                           	nop
     3b5: 48 89 84 24 d8 02 00 00      	movq	%rax, 728(%rsp)
     3bd: 48 c7 84 24 e0 02 00 00 08 00 00 00  	movq	$8, 736(%rsp)
     3c9: 48 83 c0 f8                  	addq	$-8, %rax
     3cd: 48 89 84 24 88 00 00 00      	movq	%rax, 136(%rsp)
     3d5: 48 89 84 24 18 02 00 00      	movq	%rax, 536(%rsp)
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     3dd: 48 89 84 24 20 02 00 00      	movq	%rax, 544(%rsp)
     3e5: 90                           	nop
     3e6: 48 8b 8c 24 88 00 00 00      	movq	136(%rsp), %rcx
     3ee: 48 c7 84 24 e8 02 00 00 01 00 00 00  	movq	$1, 744(%rsp)
     3fa: 48 89 8c 24 28 02 00 00      	movq	%rcx, 552(%rsp)
     402: 48 89 8c 24 30 02 00 00      	movq	%rcx, 560(%rsp)
     40a: 48 c7 c0 ff ff ff ff         	movq	$-1, %rax
     411: f0                           	lock
     412: 48 0f c1 01                  	xaddq	%rax, (%rcx)
     416: 48 89 84 24 f0 02 00 00      	movq	%rax, 752(%rsp)
     41e: 48 89 84 24 80 00 00 00      	movq	%rax, 128(%rsp)
     426: 48 8b 84 24 80 00 00 00      	movq	128(%rsp), %rax
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     42e: 48 83 f8 01                  	cmpq	$1, %rax
     432: 75 23                        	jne	0x457 <language_basics_minimal::main()+0x457>
     434: eb 00                        	jmp	0x436 <language_basics_minimal::main()+0x436>
     436: 48 8b bc 24 88 00 00 00      	movq	136(%rsp), %rdi
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     43e: 90                           	nop
     43f: 48 89 bc 24 f8 02 00 00      	movq	%rdi, 760(%rsp)
     447: 90                           	nop
     448: 48 89 bc 24 00 03 00 00      	movq	%rdi, 768(%rsp)
     450: e8 00 00 00 00               	callq	0x455 <language_basics_minimal::main()+0x455>
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     455: eb 02                        	jmp	0x459 <language_basics_minimal::main()+0x459>
     457: eb 00                        	jmp	0x459 <language_basics_minimal::main()+0x459>
     459: eb 02                        	jmp	0x45d <language_basics_minimal::main()+0x45d>
     45b: eb 00                        	jmp	0x45d <language_basics_minimal::main()+0x45d>
     45d: 48 8b 8c 24 b0 00 00 00      	movq	176(%rsp), %rcx
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     465: 48 b8 00 00 00 00 00 00 00 40	movabsq	$4611686018427387904, %rax # imm = 0x4000000000000000
     46f: 48 23 01                     	andq	(%rcx), %rax
     472: 48 83 f8 00                  	cmpq	$0, %rax
     476: 0f 84 a3 00 00 00            	je	0x51f <language_basics_minimal::main()+0x51f>
     47c: 48 8b 84 24 a8 00 00 00      	movq	168(%rsp), %rax
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     484: 48 8b 00                     	movq	(%rax), %rax
     487: 90                           	nop
     488: 48 89 84 24 d8 02 00 00      	movq	%rax, 728(%rsp)
     490: 48 c7 84 24 e0 02 00 00 08 00 00 00  	movq	$8, 736(%rsp)
     49c: 48 83 c0 f8                  	addq	$-8, %rax
     4a0: 48 89 44 24 78               	movq	%rax, 120(%rsp)
     4a5: 48 89 84 24 38 02 00 00      	movq	%rax, 568(%rsp)
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     4ad: 48 89 84 24 40 02 00 00      	movq	%rax, 576(%rsp)
     4b5: 90                           	nop
     4b6: 48 8b 4c 24 78               	movq	120(%rsp), %rcx
     4bb: 48 c7 84 24 e8 02 00 00 01 00 00 00  	movq	$1, 744(%rsp)
     4c7: 48 89 8c 24 48 02 00 00      	movq	%rcx, 584(%rsp)
     4cf: 48 89 8c 24 50 02 00 00      	movq	%rcx, 592(%rsp)
     4d7: 48 c7 c0 ff ff ff ff         	movq	$-1, %rax
     4de: f0                           	lock
     4df: 48 0f c1 01                  	xaddq	%rax, (%rcx)
     4e3: 48 89 84 24 f0 02 00 00      	movq	%rax, 752(%rsp)
     4eb: 48 89 44 24 70               	movq	%rax, 112(%rsp)
     4f0: 48 8b 44 24 70               	movq	112(%rsp), %rax
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     4f5: 48 83 f8 01                  	cmpq	$1, %rax
     4f9: 75 20                        	jne	0x51b <language_basics_minimal::main()+0x51b>
     4fb: eb 00                        	jmp	0x4fd <language_basics_minimal::main()+0x4fd>
     4fd: 48 8b 7c 24 78               	movq	120(%rsp), %rdi
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     502: 90                           	nop
     503: 48 89 bc 24 f8 02 00 00      	movq	%rdi, 760(%rsp)
     50b: 90                           	nop
     50c: 48 89 bc 24 00 03 00 00      	movq	%rdi, 768(%rsp)
     514: e8 00 00 00 00               	callq	0x519 <language_basics_minimal::main()+0x519>
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     519: eb 02                        	jmp	0x51d <language_basics_minimal::main()+0x51d>
     51b: eb 00                        	jmp	0x51d <language_basics_minimal::main()+0x51d>
     51d: eb 02                        	jmp	0x521 <language_basics_minimal::main()+0x521>
     51f: eb 00                        	jmp	0x521 <language_basics_minimal::main()+0x521>
     521: 48 8b 8c 24 c0 00 00 00      	movq	192(%rsp), %rcx
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     529: 48 b8 00 00 00 00 00 00 00 40	movabsq	$4611686018427387904, %rax # imm = 0x4000000000000000
     533: 48 23 01                     	andq	(%rcx), %rax
     536: 48 83 f8 00                  	cmpq	$0, %rax
     53a: 0f 84 a3 00 00 00            	je	0x5e3 <language_basics_minimal::main()+0x5e3>
     540: 48 8b 84 24 b8 00 00 00      	movq	184(%rsp), %rax
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     548: 48 8b 00                     	movq	(%rax), %rax
     54b: 90                           	nop
     54c: 48 89 84 24 d8 02 00 00      	movq	%rax, 728(%rsp)
     554: 48 c7 84 24 e0 02 00 00 08 00 00 00  	movq	$8, 736(%rsp)
     560: 48 83 c0 f8                  	addq	$-8, %rax
     564: 48 89 44 24 68               	movq	%rax, 104(%rsp)
     569: 48 89 84 24 58 02 00 00      	movq	%rax, 600(%rsp)
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     571: 48 89 84 24 60 02 00 00      	movq	%rax, 608(%rsp)
     579: 90                           	nop
     57a: 48 8b 4c 24 68               	movq	104(%rsp), %rcx
     57f: 48 c7 84 24 e8 02 00 00 01 00 00 00  	movq	$1, 744(%rsp)
     58b: 48 89 8c 24 68 02 00 00      	movq	%rcx, 616(%rsp)
     593: 48 89 8c 24 70 02 00 00      	movq	%rcx, 624(%rsp)
     59b: 48 c7 c0 ff ff ff ff         	movq	$-1, %rax
     5a2: f0                           	lock
     5a3: 48 0f c1 01                  	xaddq	%rax, (%rcx)
     5a7: 48 89 84 24 f0 02 00 00      	movq	%rax, 752(%rsp)
     5af: 48 89 44 24 60               	movq	%rax, 96(%rsp)
     5b4: 48 8b 44 24 60               	movq	96(%rsp), %rax
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     5b9: 48 83 f8 01                  	cmpq	$1, %rax
     5bd: 75 20                        	jne	0x5df <language_basics_minimal::main()+0x5df>
     5bf: eb 00                        	jmp	0x5c1 <language_basics_minimal::main()+0x5c1>
     5c1: 48 8b 7c 24 68               	movq	104(%rsp), %rdi
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     5c6: 90                           	nop
     5c7: 48 89 bc 24 f8 02 00 00      	movq	%rdi, 760(%rsp)
     5cf: 90                           	nop
     5d0: 48 89 bc 24 00 03 00 00      	movq	%rdi, 768(%rsp)
     5d8: e8 00 00 00 00               	callq	0x5dd <language_basics_minimal::main()+0x5dd>
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     5dd: eb 02                        	jmp	0x5e1 <language_basics_minimal::main()+0x5e1>
     5df: eb 00                        	jmp	0x5e1 <language_basics_minimal::main()+0x5e1>
     5e1: eb 02                        	jmp	0x5e5 <language_basics_minimal::main()+0x5e5>
     5e3: eb 00                        	jmp	0x5e5 <language_basics_minimal::main()+0x5e5>
     5e5: 48 8b 8c 24 98 00 00 00      	movq	152(%rsp), %rcx
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     5ed: 48 b8 00 00 00 00 00 00 00 40	movabsq	$4611686018427387904, %rax # imm = 0x4000000000000000
     5f7: 48 23 01                     	andq	(%rcx), %rax
     5fa: 48 83 f8 00                  	cmpq	$0, %rax
     5fe: 0f 84 a3 00 00 00            	je	0x6a7 <language_basics_minimal::main()+0x6a7>
     604: 48 8b 84 24 90 00 00 00      	movq	144(%rsp), %rax
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     60c: 48 8b 00                     	movq	(%rax), %rax
     60f: 90                           	nop
     610: 48 89 84 24 d8 02 00 00      	movq	%rax, 728(%rsp)
     618: 48 c7 84 24 e0 02 00 00 08 00 00 00  	movq	$8, 736(%rsp)
     624: 48 83 c0 f8                  	addq	$-8, %rax
     628: 48 89 44 24 58               	movq	%rax, 88(%rsp)
     62d: 48 89 84 24 78 02 00 00      	movq	%rax, 632(%rsp)
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     635: 48 89 84 24 80 02 00 00      	movq	%rax, 640(%rsp)
     63d: 90                           	nop
     63e: 48 8b 4c 24 58               	movq	88(%rsp), %rcx
     643: 48 c7 84 24 e8 02 00 00 01 00 00 00  	movq	$1, 744(%rsp)
     64f: 48 89 8c 24 88 02 00 00      	movq	%rcx, 648(%rsp)
     657: 48 89 8c 24 90 02 00 00      	movq	%rcx, 656(%rsp)
     65f: 48 c7 c0 ff ff ff ff         	movq	$-1, %rax
     666: f0                           	lock
     667: 48 0f c1 01                  	xaddq	%rax, (%rcx)
     66b: 48 89 84 24 f0 02 00 00      	movq	%rax, 752(%rsp)
     673: 48 89 44 24 50               	movq	%rax, 80(%rsp)
     678: 48 8b 44 24 50               	movq	80(%rsp), %rax
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     67d: 48 83 f8 01                  	cmpq	$1, %rax
     681: 75 20                        	jne	0x6a3 <language_basics_minimal::main()+0x6a3>
     683: eb 00                        	jmp	0x685 <language_basics_minimal::main()+0x685>
     685: 48 8b 7c 24 58               	movq	88(%rsp), %rdi
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     68a: 90                           	nop
     68b: 48 89 bc 24 f8 02 00 00      	movq	%rdi, 760(%rsp)
     693: 90                           	nop
     694: 48 89 bc 24 00 03 00 00      	movq	%rdi, 768(%rsp)
     69c: e8 00 00 00 00               	callq	0x6a1 <language_basics_minimal::main()+0x6a1>
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     6a1: eb 02                        	jmp	0x6a5 <language_basics_minimal::main()+0x6a5>
     6a3: eb 00                        	jmp	0x6a5 <language_basics_minimal::main()+0x6a5>
     6a5: eb 02                        	jmp	0x6a9 <language_basics_minimal::main()+0x6a9>
     6a7: eb 00                        	jmp	0x6a9 <language_basics_minimal::main()+0x6a9>
     6a9: 48 8b 8c 24 d0 00 00 00      	movq	208(%rsp), %rcx
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     6b1: 48 b8 00 00 00 00 00 00 00 40	movabsq	$4611686018427387904, %rax # imm = 0x4000000000000000
     6bb: 48 23 01                     	andq	(%rcx), %rax
     6be: 48 83 f8 00                  	cmpq	$0, %rax
     6c2: 0f 84 a3 00 00 00            	je	0x76b <language_basics_minimal::main()+0x76b>
     6c8: 48 8b 84 24 c8 00 00 00      	movq	200(%rsp), %rax
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     6d0: 48 8b 00                     	movq	(%rax), %rax
     6d3: 90                           	nop
     6d4: 48 89 84 24 d8 02 00 00      	movq	%rax, 728(%rsp)
     6dc: 48 c7 84 24 e0 02 00 00 08 00 00 00  	movq	$8, 736(%rsp)
     6e8: 48 83 c0 f8                  	addq	$-8, %rax
     6ec: 48 89 44 24 48               	movq	%rax, 72(%rsp)
     6f1: 48 89 84 24 98 02 00 00      	movq	%rax, 664(%rsp)
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     6f9: 48 89 84 24 a0 02 00 00      	movq	%rax, 672(%rsp)
     701: 90                           	nop
     702: 48 8b 4c 24 48               	movq	72(%rsp), %rcx
     707: 48 c7 84 24 e8 02 00 00 01 00 00 00  	movq	$1, 744(%rsp)
     713: 48 89 8c 24 a8 02 00 00      	movq	%rcx, 680(%rsp)
     71b: 48 89 8c 24 b0 02 00 00      	movq	%rcx, 688(%rsp)
     723: 48 c7 c0 ff ff ff ff         	movq	$-1, %rax
     72a: f0                           	lock
     72b: 48 0f c1 01                  	xaddq	%rax, (%rcx)
     72f: 48 89 84 24 f0 02 00 00      	movq	%rax, 752(%rsp)
     737: 48 89 44 24 40               	movq	%rax, 64(%rsp)
     73c: 48 8b 44 24 40               	movq	64(%rsp), %rax
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     741: 48 83 f8 01                  	cmpq	$1, %rax
     745: 75 20                        	jne	0x767 <language_basics_minimal::main()+0x767>
     747: eb 00                        	jmp	0x749 <language_basics_minimal::main()+0x749>
     749: 48 8b 7c 24 48               	movq	72(%rsp), %rdi
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     74e: 90                           	nop
     74f: 48 89 bc 24 f8 02 00 00      	movq	%rdi, 760(%rsp)
     757: 90                           	nop
     758: 48 89 bc 24 00 03 00 00      	movq	%rdi, 768(%rsp)
     760: e8 00 00 00 00               	callq	0x765 <language_basics_minimal::main()+0x765>
;     print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))
     765: eb 02                        	jmp	0x769 <language_basics_minimal::main()+0x769>
     767: eb 00                        	jmp	0x769 <language_basics_minimal::main()+0x769>
     769: eb 02                        	jmp	0x76d <language_basics_minimal::main()+0x76d>
     76b: eb 00                        	jmp	0x76d <language_basics_minimal::main()+0x76d>
; def main():
     76d: 48 81 c4 08 03 00 00         	addq	$776, %rsp              # imm = 0x308
     774: c3                           	retq
     775: 66 66 2e 0f 1f 84 00 00 00 00 00     	nopw	%cs:(%rax,%rax)

リスト-2: language_basics_minimal.asm

7.2. リスト-2 を段階的に読む

全体を段階的に解説します。オフセットや命令列は、手元の objdump 結果と Mojo / LLVM の版によってわずかに変わり得ますが、リスト-2 のダンプを前提に読み進めてください。ニモニックは5 章 と同様に AT&T 記法です。

7.2.1. 関数プロローグ

0: subq $776, %rsp

スタックに 776 バイトを確保します。5 章136 バイトより大きいのは、複数の変数・文字列オブジェクト・引数用テーブルを すべてスタック上に載せるためです。

7.2.2. ① 変数の初期化(コンパイル時定数の最適化)

; var n: Int = 42
7: movq $42, 232(%rsp)

; var doubled = n * 2
13: movq $84, 240(%rsp)

注目点は、n * 2 の計算が コンパイル時に完了 しています。42 * 2 = 84 がそのまま即値として埋め込まれており、実行時に乗算命令は一切発生しません。Mojo コンパイラ(LLVM)の 定数畳み込み最適化です。

7.2.3. List[Int] = [1, 2, 3] の構築

; 要素をスタックに配置
1f: movq $1, 272(%rsp)
2b: movq $2, 280(%rsp)
37: movq $3, 288(%rsp)

まず 3 つの整数をスタック上に並べます。

; 各要素へのポインタのテーブル
43: leaq 272(%rsp), %rax
4b: movq %rax, 296(%rsp)   ; &xs[0]
53: leaq 280(%rsp), %rax
5b: movq %rax, 304(%rsp)   ; &xs[1]
63: leaq 288(%rsp), %rax
6b: movq %rax, 312(%rsp)   ; &xs[2]

要素アドレスのテーブルを組み立てます。Mojo の List は、内部で 要素を指すポインタ列を持つ形としてコードが生成されます。

73: movl $3, %esi           ; 要素数 = 3
78: leaq 296(%rsp), %rdi    ; ポインタテーブルの先頭
; メタデータを 2 箇所にコピー(後で説明)
81: movq %rdi, 696(%rsp)
89: movq $3, 704(%rsp)
96: movq %rdi, 712(%rsp)
9e: movq $3, 720(%rsp)

aa: leaq 248(%rsp), %rdx    ; List 本体の格納先
b2: callq ...               ; List 構築関数の呼び出し

7.2.4. List 構築後の後処理

b7: leaq 327(%rsp), %rdi
bf: callq ...               ; 内部初期化(アロケータ等)

List の内部状態を整える 追加の呼び出しです。

7.2.5. String("count") の構築

5 章Hello, Mojo と同型です。 文字列オブジェクトは データポインタ・長さ・タグビット・関数ポインタ 2 本 というワード列でスタック上に現れます。 "count" 以降の "n="" sum=" なども、同じレイアウトで繰り返し構築されます。

7.2.6. print() の引数構築(もっとも複雑な部分)

print(String("n="), n, String(" sum="), doubled, String(" "), label, String("="), len(xs))8 引数のために、広いアドレス範囲で準備が続きます。

1332db 付近では、次の文字列リテラルが ほぼ同じ手順で構築されます。

アドレス範囲(目安)

構築している文字列

長さ

133186

"n="

2

18e1f5

" sum="

5

1fd264

" "

1

26c2d3

"="

1

各オブジェクトは、第④と同様のレイアウト(データポインタ・長さ・タグ・関数ポインタ 2 本)で並びます。

; len(xs) の取得
2dc: movq 256(%rsp), %rax
2e4: movq %rax, 216(%rsp)   ; len(xs) の結果を保存

ここでは、直前の処理で取得した len(xs) の結果がスタック上の 256(%rsp) に格納されており、それを別の場所へコピーしています。

7.2.7. print() 本体の呼び出し

x86-64 のレジスタ引数(rdir9 の 6 本)だけでは 8 引数を渡しきれないため、スタック上に引数テーブルを組み立ててから呼び出す経路が現れます。

368: leaq 368(%rsp), %rdi   ; String("n=")
370: leaq 408(%rsp), %rdx   ; String(" sum=")
378: leaq 448(%rsp), %r8    ; String(" ")
380: leaq 328(%rsp), %r9    ; label = String("count")
388: callq ...              ; print() 本体

7.2.8. ⑦ エラーチェックとデストラクタ処理(5 回繰り返し)

print() のあと、スタック上に作った文字列オブジェクトごとに、第1部第2章と同型の 後片付けパターンが繰り返されます(リスト上は次のような区間に現れます)。

  • 38d45bString("n=")

  • 45d51fString(" sum=")

  • 5215e3String(" ")

  • 5e56a7String("count")

  • 6a976bString("=")

各ブロックは、おおむね次の骨格です。

; ① エラーフラグチェック
movabsq $0x4000000000000000, %rax
andq (フラグ保存場所), %rax
cmpq $0, %rax
je → エラーなし → スキップ

; ② エラーあり → refcount をアトミックにデクリメント
movq $-1, %rax
lock xaddq %rax, (%rcx)

; ③ 旧 refcount が 1 か(最後の参照か)
cmpq $1, %rax
jne → 他に参照あり → スキップ

; ④ 最後の参照 → 解放/デストラクタ
movq ..., %rdi
callq ...

; ⑤ ランディングパッド(4 つの jmp)
; eb 02 / eb 00 / eb 02 / eb 00

同じ形が 5 回分 繰り返されるため、コードが非常に長くなります。

7.2.9. 関数エピローグ

76d: addq $776, %rsp        ; スタック解放
774: retq                   ; 呼び出し元へ戻る
775: nopw %cs:(%rax,%rax)   ; アライメント用パディング

末尾の nopw は、次の関数の先頭を 16 バイト境界に合わせるためのパディングです。今回は 11 バイトと長くなっていますが、これは必要なパディング量が多かったためです。

7.2.10. 全体の流れ(まとめ)

スタック確保(776 バイト)
  ↓
n = 42, doubled = 84 を配置(定数はコンパイル時に畳み込み済み)
  ↓
List[Int]{1,2,3} をスタック上に構築
  ↓
String("count") をスタック上に構築
  ↓
print 用の文字列リテラルを構築("n=", " sum=", " ", "=")
  ↓
len(xs) を取得
  ↓
引数テーブルを組み立てて print() 呼び出し
【後片付け × 5 回】各 String について:エラーチェック → refcount デクリメント → 必要なら解放
  ↓
スタック解放・return

5 章Hello, Mojo と比べると、同じ「文字列を組み立てる → 後片付けする」パターンが、引数の数だけ機械的に繰り返される点が大きな違いです。Mojo が 文字列リテラルを含む引数ごとに独立したオブジェクトとして扱い、それぞれ参照カウントで管理する様子が、ダンプから追いやすくなっています。