2009-11-30 9 views
5

私はそれは、Cライブラリの呼び出しの一部でセグメンテーションフォールトが発生し、次のアセンブリコード組立セグメンテーションフォールト

#cpuid using C library Functions 
.section .data 
output: 
.asciz "The Processor Vendor ID is '%s'\n" 
.section .bss 
.lcomm buffer, 12 
.section .text 
.globl main 
main: 
movq $0, %rax 
cpuid 
movq $buffer, %rdi 
movq %rbx, (%rdi) 
movq %rdx, (%rdi) 
movq %rcx, (%rdi) 
pushq $buffer 
pushq $output 
call printf 
addq $8, %rsp 
pushq $0 
call exit 

の走行時にエラーが発生しました:コールのprintf をそれはx86_64のモードで実行されています。 私はCライブラリに関するx64コードのコンパイル中に逃したものは何もありませんか?またはアセンブリでのコード

おかげ

+2

は、それらのMOVQの – Managu

+1

感謝の間に適切な量だけ%のRDIを増やすことができますみんな、私は問題を解決した。 /lib/ld-linux-x86-64.so.2で手作業でインストールした後に読み込んだのは間違ったlibでしたが、main関数を_startに置き換えました。 私はそれを動的リンクとして使いました。 悪い英語のため申し訳ありません –

答えて

0

慣れていないので、暗闇の中でのショットに何か問題があります:両方のあなたの文字列がヌルで終了していますか?

+0

'.asciz'は自動的に終端nullを追加します。 – querist

4

Cランタイムライブラリの初期化が呼び出されていますか?それはstdoutがセットアップされるためには最初に実行されなければなりません。ところで、スタックトレースは、問題の原因を疑いなくするでしょう。

また、%s変換が%.12sでバッファをオーバーフローさせないようにするか、バッファの後にNULバイトを置くだけで済みます。

0

1つの単語の上に3回書くのではなく、$ bufferに書き込む文字列をNULL終了させる必要があります。また、ウォリックは正しいです:あなたはCRTが初期化されていると確信していますか?

正に、あなたはC言語でCライブラリ関数を呼び出すこのプログラムを書いているほうがずっと良いです。CPUIDコードを__cdecl関数内のインラインアセンブリとして書き、その結果を文字列ポインタに書き込ませてからその関数をCプログラムから呼び出します。 64ビットfprintfのため

void GetCPUID(char *toStr) 
{ 
// inline assembly left as exercise for the reader.. 
// write ebx to *toStr, ecx to *toStr+4, edx to *toStr+8, and 0 to *toStr+12 
} 

void PrintCPUID() 
{ 
    char cpuidstr[16]; 
    GetCPUID(cpuidstr); 
    printf("cpuid: %s\n", cpuidstr); 

} 
2

アセンブラコールは一見変わっ、そのいずれかの32ビットライブラリをリンクしたり、次のコードを使用しています

#cpuid using C library Functions 
.section .data 
output: 
.asciz "The Processor Vendor ID is '%s'\n" 
.section .bss 
.lcomm buffer, 12 
.section .text 
.globl main 
main: 
movq $0, %rax 
cpuid 
movq $buffer, %rdi 
movq %rbx, (%rdi) 
movq %rdx, 4(%rdi) 
movq %rcx, 8(%rdi) 
movq $buffer, %rsi #1st parameter 
movq $output, %rdi #2nd parameter 
movq $0, %rax 
call printf 
addq $8, %rsp 
pushq $0 
call exit 
+0

あなたのmovq命令は '(%rdi)'を増やさないので、何かが見つからない限り、 'movq $ buffer、(%rdi)'はあなたの 'movq $ output、%rdi'によって単純に上書きされます後でライン。とにかく後で何行か '%rsi'に' $ buffer'をコピーするときに '%rdi'を使うのはなぜですか? – querist

関連する問題