0

(C/C++ ではなく、NASM 用の純粋な x86 アセンブリで書いています。)

コンパイルされたバイナリを実行すると、セグメンテーション違反が発生します。これは古くからあるエラー メッセージであることは承知していますが、セグメンテーション違反のこの特定のインスタンスを検索しても効果があるとは証明されていません。

ENTER 616,0gdb は、呼び出しの開始時に障害が発生したことを示唆しています。古い をプッシュして%rbpに格納%rspし、ローカル変数のバイト数を%rbp減らすのと同じだと思います。%rsp616

ここでセグメンテーション違反が発生する理由について、より多くの経験を持つ人はヒントを持っていますか? メモリアクセスの問題の奇妙な場所のように思えます-頭に浮かぶ唯一のことは、616が値を減らすのにたくさんあるかもしれないということですが、それ以外は私を困惑させています. 許可されるサイズに制限はありますか (使用可能なメモリの合計量以外に)?

どんな助けでも大歓迎です。

更新: 役に立った場合、これは長い一連の再帰呼び出しの終わりではありません:

(gdb) backtrace
#0  0x00000000004005e0 in user_func ()
#1  0x0000000000400e69 in if4 ()
#2  0xffffffffffffffff in ?? ()
#3  0xffffffffffffffff in ?? ()
#4  0x0000000000000000 in ?? ()

(gdb) frame 0
#0  0x00000000004005e0 in user_func ()

(gdb) disassemble
Dump of assembler code for function user_partition:
=> 0x00000000004005e0 <+0>:     enterq $0x2b0,$0x0
   0x00000000004005e4 <+4>:     push   %r15
   0x00000000004005e6 <+6>:     push   %r12
   0x00000000004005e8 <+8>:     push   %r13
   0x00000000004005ea <+10>:    push   %r14
   ...

更新 2: バックトレースは破損したスタック ポインターを示しているように見えるため、各メソッド呼び出しがどのように見えるかに関する関連する詳細を次に示します。

user_func:                           
   ENTER      296, 0                         
   PUSH       R13      ; Saving any callee-saved registers used in main body   
   PUSH       R15     
   PUSH       R14     
   PUSH       R12     
   ; Only opcodes to MOV between temp registers and [ RBP - x ]
   MOV        RAX, 0                        
   POP        R12      ; Restoring the callee-saved registers    
   POP        R14
   POP        R15
   POP        R13
   LEAVE                                    
   RET                                      

物事をプッシュ/ポップするという点で、ここで何か間違ったことをした可能性はありますか? LEAVE前のPOPは私には正しいように思えました...

4

1 に答える 1

1

0x0000000000000バックトレースのおよびのような値は0xffffffffffff、ある時点でスタックを破棄したことを示します(戻り値などを上書きしました)。スタックポインタがガベージである可能性が高いため、スタックポインタにプッシュするとセグメンテーション違反が発生する可能性が高くなります。

于 2012-05-04T21:06:40.303 に答える