(リンクでPDF。書く都合でA3にしたけど、A4で印刷しても読めると思う。)
本当はそれぞれに対して絵をつけたかったんだけど、それどころではなかった。
勉強のために書いたくらいで全然詳しくないので、間違っているところがあればぜひ教えてくださいまし。
以下余談。
興味深いのは、64bit版のcl.exe(on Windows)とgcc(on Linux)の挙動の違い。関数の引数をスタックにpushするときに、cl.exeではraxに入れてからメモリに置くんだけど、gccはDWORDで区切ってそのままメモリに置く。最適化なし(/Odと-O0)なので、-O2とかにすればまた違うんだろうけどね。
cl.exe版(cl /Od /Zi):
0000000140001030: 48 83 EC 58 sub rsp,58h
0000000140001034: 48 B8 08 00 FF FF mov rax,0AAAAFFFF0008h
AA AA 00 00
000000014000103E: 48 89 44 24 38 mov qword ptr [rsp+38h],rax
0000000140001043: 48 B8 07 00 FF FF mov rax,0AAAAFFFF0007h
AA AA 00 00
000000014000104D: 48 89 44 24 30 mov qword ptr [rsp+30h],rax
0000000140001052: 48 B8 06 00 FF FF mov rax,0AAAAFFFF0006h
AA AA 00 00
000000014000105C: 48 89 44 24 28 mov qword ptr [rsp+28h],rax
0000000140001061: 48 B8 05 00 FF FF mov rax,0AAAAFFFF0005h
AA AA 00 00
000000014000106B: 48 89 44 24 20 mov qword ptr [rsp+20h],rax
0000000140001070: 49 B9 04 00 FF FF mov r9,0AAAAFFFF0004h
AA AA 00 00
000000014000107A: 49 B8 03 00 FF FF mov r8,0AAAAFFFF0003h
AA AA 00 00
0000000140001084: 48 BA 02 00 FF FF mov rdx,0AAAAFFFF0002h
AA AA 00 00
000000014000108E: 48 B9 01 00 FF FF mov rcx,0AAAAFFFF0001h
AA AA 00 00
0000000140001098: E8 6D FF FF FF call @ILT+5(callee)
gcc版(gcc -O0):
400498: 48 83 ec 20 sub rsp,0x20 40049c: c7 44 24 08 08 00 ff mov DWORD PTR [rsp+0x8],0xffff0008 4004a3: ff 4004a4: c7 44 24 0c aa aa 00 mov DWORD PTR [rsp+0xc],0xaaaa 4004ab: 00 4004ac: c7 04 24 07 00 ff ff mov DWORD PTR [rsp],0xffff0007 4004b3: c7 44 24 04 aa aa 00 mov DWORD PTR [rsp+0x4],0xaaaa 4004ba: 00 4004bb: 49 b9 06 00 ff ff aa mov r9,0xaaaaffff0006 4004c2: aa 00 00 4004c5: 49 b8 05 00 ff ff aa mov r8,0xaaaaffff0005 4004cc: aa 00 00 4004cf: 48 b9 04 00 ff ff aa mov rcx,0xaaaaffff0004 4004d6: aa 00 00 4004d9: 48 ba 03 00 ff ff aa mov rdx,0xaaaaffff0003 4004e0: aa 00 00 4004e3: 48 be 02 00 ff ff aa mov rsi,0xaaaaffff0002 4004ea: aa 00 00 4004ed: 48 bf 01 00 ff ff aa mov rdi,0xaaaaffff0001 4004f4: aa 00 00 4004f7: e8 06 00 00 00 call 400502
たぶん、movは即値ではQWORDに詰められないんだろうね。
おまけとして、別のアーキテクチャでやったらどうか?ということで、x86版のCコードをARMで試してみた。
00008398 <caller>:
8398: e92d4800 push {fp, lr}
839c: e28db004 add fp, sp, #4
83a0: e24dd008 sub sp, sp, #8
83a4: e59f0020 ldr r0, [pc, #32] ; 83cc
83a8: e59f1020 ldr r1, [pc, #32] ; 83d0
83ac: e59f2020 ldr r2, [pc, #32] ; 83d4
83b0: e59f3020 ldr r3, [pc, #32] ; 83d8
83b4: eb000008 bl 83dc
83b8: e1a03000 mov r3, r0
83bc: e50b3008 str r3, [fp, #-8]
83c0: e24bd004 sub sp, fp, #4
83c4: e8bd4800 pop {fp, lr}
83c8: e12fff1e bx lr
83cc: ffff0001 .word 0xffff0001
83d0: ffff0002 .word 0xffff0002
83d4: ffff0003 .word 0xffff0003
83d8: ffff0004 .word 0xffff0004
000083dc <callee>:
83dc: e52db004 push {fp} ; (str fp, [sp, #-4]!)
83e0: e28db000 add fp, sp, #0
83e4: e24dd01c sub sp, sp, #28
83e8: e50b0010 str r0, [fp, #-16]
83ec: e50b1014 str r1, [fp, #-20]
83f0: e50b2018 str r2, [fp, #-24]
83f4: e50b301c str r3, [fp, #-28]
83f8: e51b2010 ldr r2, [fp, #-16]
83fc: e51b3014 ldr r3, [fp, #-20]
8400: e0823003 add r3, r2, r3
8404: e50b300c str r3, [fp, #-12]
8408: e51b200c ldr r2, [fp, #-12]
840c: e51b3018 ldr r3, [fp, #-24]
8410: e0633002 rsb r3, r3, r2
8414: e50b300c str r3, [fp, #-12]
8418: e51b200c ldr r2, [fp, #-12]
841c: e51b101c ldr r1, [fp, #-28]
8420: e0030291 mul r3, r1, r2
8424: e50b3008 str r3, [fp, #-8]
8428: e51b3008 ldr r3, [fp, #-8]
842c: e1a00003 mov r0, r3
8430: e28bd000 add sp, fp, #0
8434: e8bd0800 pop {fp}
8438: e12fff1e bx lr
さすがに違うね。

0 件のコメント:
コメントを投稿