Cソースの一部アセンブラ化に慣れてきました。
今回はビットシフトをアセンブラに置き換えてみます。
では、元ソース。0xffを左に1ビットシフトするプログラムです。
takk@deb9:~/tmp$ cat -n t.c 1 #include <stdio.h> 2 int main() 3 { 4 unsigned long a; 5 a = 0xff; 6 a = a << 1; 7 printf("%08x\n",a); 8 } takk@deb9:~/tmp$
実行すると、最下位bitには0が入って0x1feになります。
takk@deb9:~/tmp$ gcc t.c takk@deb9:~/tmp$ ./a.out 000001fe takk@deb9:~/tmp$
objdump -dでmain関数のアセンブラを見てみます。
00000000000006b0 <main>: 6b0: 55 push %rbp 6b1: 48 89 e5 mov %rsp,%rbp 6b4: 48 83 ec 10 sub $0x10,%rsp 6b8: 48 c7 45 f8 ff 00 00 movq $0xff,-0x8(%rbp) 6bf: 00 6c0: 48 d1 65 f8 shlq -0x8(%rbp) 6c4: 48 8b 45 f8 mov -0x8(%rbp),%rax 6c8: 48 89 c6 mov %rax,%rsi 6cb: 48 8d 3d a2 00 00 00 lea 0xa2(%rip),%rdi # 774 <_IO_stdin_used+0x4> 6d2: b8 00 00 00 00 mov $0x0,%eax 6d7: e8 84 fe ff ff callq 560 <printf@plt> 6dc: b8 00 00 00 00 mov $0x0,%eax 6e1: c9 leaveq 6e2: c3 retq 6e3: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) 6ea: 00 00 00 6ed: 0f 1f 00 nopl (%rax)
ビットシフトっぽい、shlq命令が使われていますが、シフト量を指定している箇所が見つかりません。
2ビットシフトでビルドして、再度アセンブラを見てみることにします。
takk@deb9:~/tmp$ cat -n t.c 1 #include <stdio.h> 2 int main() 3 { 4 unsigned long a; 5 a = 0xff; 6 a = a << 2; 7 printf("%08x\n",a); 8 } takk@deb9:~/tmp$ gcc t.c takk@deb9:~/tmp$ ./a.out 000003fc takk@deb9:~/tmp$
00000000000006b0 <main>: 6b0: 55 push %rbp 6b1: 48 89 e5 mov %rsp,%rbp 6b4: 48 83 ec 10 sub $0x10,%rsp 6b8: 48 c7 45 f8 ff 00 00 movq $0xff,-0x8(%rbp) 6bf: 00 6c0: 48 c1 65 f8 02 shlq $0x2,-0x8(%rbp) 6c5: 48 8b 45 f8 mov -0x8(%rbp),%rax 6c9: 48 89 c6 mov %rax,%rsi 6cc: 48 8d 3d a1 00 00 00 lea 0xa1(%rip),%rdi # 774 <_IO_stdin_used+0x4> 6d3: b8 00 00 00 00 mov $0x0,%eax 6d8: e8 83 fe ff ff callq 560 <printf@plt> 6dd: b8 00 00 00 00 mov $0x0,%eax 6e2: c9 leaveq 6e3: c3 retq 6e4: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) 6eb: 00 00 00 6ee: 66 90 xchg %ax,%ax
シフト量1bitと2bit見比べてみます。
1bitシフト
6c0: 48 d1 65 f8 shlq -0x8(%rbp)
2bitシフト
6c0: 48 c1 65 f8 02 shlq $0x2,-0x8(%rbp)
1bitの場合は、シフト量のパラメータが不要なんですね。
では、Cソースを、アセンブラに置き換えて実行してみましょう。
takk@deb9:~/tmp$ cat -n t.c 1 #include <stdio.h> 2 int main() 3 { 4 unsigned long a; 5 a = 0xff; 6 asm("shlq -0x8(%rbp)"); 7 printf("%08x\n",a); 8 } takk@deb9:~/tmp$ gcc t.c takk@deb9:~/tmp$ ./a.out 000001fe takk@deb9:~/tmp$
うまくいきました。
次は、右シフトをやってみます。
左シフトがshlqだったので、右ソフトはおそらく、shrqってところでしょう。
takk@deb9:~/tmp$ cat -n t.c 1 #include <stdio.h> 2 int main() 3 { 4 unsigned long a; 5 a = 0x8ff; 6 asm("shrq $3,-0x8(%rbp)"); 7 printf("%08x\n",a); 8 } takk@deb9:~/tmp$ gcc t.c takk@deb9:~/tmp$ ./a.out 0000011f takk@deb9:~/tmp$
当てずっぽうでしたが、うまくいきました。
コメント