2016-06-21 10 views
1

次の短いプログラムを検討してください。Segfault on movq命令ですか?

int main(){      
    asm("movq 0x5F5E100, %rcx;" 
      "startofloop: ; "  
      "sub 0x1, %rcx; "  
      "jne startofloop; "); 
}         

このプログラムは罰金コンパイルし、それが実行されたとき、それは最初のmovq命令にセグメンテーションフォールト。

私は明白なものを紛失しているはずですが、ここの誰かが私にそれを指摘してくれることを願っています。

私はDebian 8でカーネル3.16.0-4-amd64を実行しています。


将来参照するために、これはコンパイラが生成したものです。

main:                 
.LFB0:                 
    .cfi_startproc              
    pushq %rbp              
    .cfi_def_cfa_offset 16            
    .cfi_offset 6, -16             
    movq %rsp, %rbp             
    .cfi_def_cfa_register 6            
#APP                 
# 2 "asm_fail.c" 1              
    movq 0x5F5E100, %rcx;startofloop: ; sub 0x1, %rcx; jne startofloop; 
# 0 "" 2                
#NO_APP                 
+0

私はアセンブリについてほとんど何も知らない。しかし、値0x5F5E100を%rcxにコピーして、それを実現せずにオペランドを入れ替えたいと思ったのでしょうか? – andre

+0

あなたの質問にコンパイラ生成のアセンブリコード( '-S'でコンパイル)を追加してください。 – user3386109

答えて

3

それはあまりにも長い間、私は、ASMを書かれていることからなっている、と私は1つのAT & T構文で$と即値を前置きしなければならないことを忘れていたことが判明します。私は&のT構文を再確認するときに通知hereを見つけました。

asm("movq $100000000, %rcx;" 
     "startofloop: ; " 
     "sub $0x1, %rcx; " 
     "jne startofloop; "); 
+0

角括弧がメモリオペランドを指定していることが分かっているなら、Intelの構文で逆アセンブルすると、 'mov r64、imm32'の代わりに' mov r64、r/m64'を使用していることがわかります。 (例: 'objdump -Mintel -drw foo.o') –