(リンクで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] ; 83cc83a8: 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 件のコメント:
コメントを投稿