アセンブラの勉強(1)
Mona等のソースコードをそのまま64ビットgccにかけるとインラインアセンブラの部分でそんな構文は使えないよというエラーが出ます。使えないといわれてもどうしたらいいのか途方にくれていたらKタンに簡単なコードをgccに食わせて、どう変換されているか見たらどうかとアドバイスを受けました。たしか"gcc -S"でアセンブラソースを吐くオプションがあったはずなのでいろいろ調べてみました。
ソースコード
int main(void) { /* この部分に注目 */ char a = 0xff; short b = 0xffff; int c = 0xffffffff; long d = 0xffffffff; a++; b++; c++; d++; /* この部分に注目 */ return 0xff; }
32ビットコード
gcc -m32 -S -O0 -Wall test01.c movb $-1, -1(%ebp) movw $-1, -4(%ebp) movl $-1, -8(%ebp) movl $-1, -12(%ebp) leal -1(%ebp), %eax incb (%eax) leal -4(%ebp), %eax incw (%eax) leal -8(%ebp), %eax incl (%eax) leal -12(%ebp), %eax incl (%eax) movl $255, %eax leave ret
64ビットコード
gcc -S -O0 -Wall test01.c movb $-1, -1(%rbp) movw $-1, -4(%rbp) movl $-1, -8(%rbp) movl $-1, -16(%rbp) movl $0, -12(%rbp) leaq -1(%rbp), %rax incb (%rax) leaq -4(%rbp), %rax incw (%rax) leaq -8(%rbp), %rax incl (%rax) leaq -16(%rbp), %rax incq (%rax) movl $255, %eax leave ret
64ビット用インラインアセンブラ
asm volatile( "movb $-1, -1(%rbp)\n" "movw $-1, -4(%rbp)\n" "movl $-1, -8(%rbp)\n" "movl $-1, -16(%rbp)\n" "movl $0, -12(%rbp)\n" "leaq -1(%rbp), %rax\n" "incb (%rax)\n" "leaq -4(%rbp), %rax\n" "incw (%rax)\n" "leaq -8(%rbp), %rax\n" "incl (%rax)\n" "leaq -16(%rbp), %rax\n" "incq (%rax)\n" );
違い
- 使用するレジスタが変わっている(eax->rax、ebp->rbp)
- 通常演算の多くにq(64ビット用)がつくようになっている
- %%eaxが(%rax)に変わっている
- インラインアセンブラの移植性が低いというのはこういうことだったのかと納得・・