0

私のコード

const int howmany = 5046;
char buffer[howmany];
    asm("lea     buffer,%esi"); //Get the address of buffer
    asm("mov     howmany,%ebx");         //Set the loop number
    asm("buf_loop:");                      //Lable for beginning of loop
    asm("movb     (%esi),%al");             //Copy buffer[x] to al
    asm("inc     %esi");                   //Increment buffer address
    asm("dec     %ebx");                   //Decrement loop count
    asm("jnz     buf_loop");              //jump to buf_loop if(ebx>0)

私の問題

gccコンパイラを使用しています。何らかの理由で、私のバッファ/howmany変数は私のasmの目には定義されていません。理由はわかりません。バッファ配列の開始アドレスをesiレジスタに移動し、各要素をalレジスタにコピーしながら「何回」ループさせたいだけです。

4

3 に答える 3

7

gcc でインライン アセンブラを使用していますか? (そうでない場合、他のどの C++ コンパイラで正確に?)

gcc の場合は、こちらの詳細を参照してください。具体的には、次の例を参照してください。

    asm ("leal (%1,%1,4), %0"
         : "=r" (five_times_x)
         : "r" (x) 
         );

%0および%1は C レベルの変数を参照しており、2 番目 (出力用) および 3 番目 (入力用) のパラメーターとして具体的にリストされていますasm。あなたの例では、「入力」しかないため、空の2番目のオペランドがあります(伝統的に、コロンの後にコメントを使用して/* no output registers */、より明示的に示します)。

于 2009-12-24T02:47:51.350 に答える
1

そのような配列を宣言する部分

int howmany = 5046;
char buffer[howmany];

有効な C++ ではありません。C++ では、「可変」または実行時のサイズを持つ配列を宣言することはできません。C++ 配列宣言では、サイズは常にコンパイル時の定数です。

コンパイラがこの配列宣言を許可している場合、それは拡張機能として実装されていることを意味します。その場合、そのような実行時サイズの配列を内部で実装する方法を理解するために、独自の調査を行う必要があります。内部的には真の配列としてではなく、ポインタbufferとして実装されると思います。私の推測が正しく、それが実際にポインターである場合、配列のアドレスをロードする適切な方法は次のようになりますesi

mov buffer,%esi

leaコードのように、ではありません。lea「通常の」コンパイル時サイズの配列でのみ機能しますが、実行時サイズの配列では機能しません。

もう 1 つの問題は、実行時のサイズの配列がコードに本当に必要かどうかです。間違ってそうしてしまったのではないでしょうか?単にhowmany宣言を次のように変更すると、

const int howmany = 5046;

配列は「通常の」C++ 配列に変わり、コードはそのまま (つまり を使用してlea) 動作し始める可能性があります。

于 2009-12-24T02:49:25.037 に答える