2016-11-21 1 views
0

基本的にC関数を呼び出し、返された値を取得し、その値をパラメータとして別の関数に渡して文字を返すこの関数を使用します。インラインアセンブリを使用してC関数から返されるcharを取得します

void convertText(FILE *arch, FILE *result) 
{ 
    int i = 0; 
    int n = arch->size; 

    _asm { 
    mov esi, 0 
whileS: 
    cmp esi, n 
    jge end 

    mov ebx, result 
    mov ebx, [ebx]result.information ; Pointer to an array of characters 

    push esi ; Push parameters to get5bitsFunc 
    push arch ; Push parameters to get5bitsFunc 

    call get5bitsFunc 
    pop arch ; Restore values 
    pop esi ; Restore values 

    push eax ; push get5bitsFunc returned value to codify as parameter 
    call codify 
    mov edi, eax ; <- HERE move returned value from codify to edi register 
    pop eax ; restore eax 

    inc esi 
    jmp whileS 
end: 

    } 
} 

タイプ

unsigned char codify(unsigned char parameter) { 
    unsigned char resp; 

    // Do something to the parameter 
    resp = 'b'; // asign value to resp 
    return resp; 
} 

の関数として成文化するのだと思う私はすでに成文化するをテストし、私はCコードを使用する値を返す正常に動作しています。問題は、インラインアセンブリーのconvertTextコードを " - > Here"とマークした行でデバッグすると、eaxで返される値が3424242タイプで、97以上がASCIIテーブルにあることです私は欲しい。

どのようにしてchar値を取得できますか?

+0

'unsigned char'は1バイトだけですが、' eax'は32ビット(4バイト)のレジスタです。 'codify()'が1バイトだけを返す場合、戻り値は残りの 'eax'をそのまま残して(ゴミになる)' al'( 'eax'の最初のバイト)に格納されます。 'codify()'を呼び出す前に 'xor eax、eax'をお勧めしますので、戻り値を格納する前にレジスタがクリーンであることを知っておいてください。 –

+0

@BrendonBoldtええ、ありがとうございました。あなたのコメントを答えとして投稿して、私があなたのことを正しいと確認できるかい? – ravelinx

+0

なぜあなたは 'pop eaxですか?リストアeax'?確かにスタックを再バランスするのは、次の反復では 'get5bitsFunc'を呼び出す前にそれを読んでいないからです。命令は正しいが、コメントは完全に間違っている/誤解を招く。同様に、その呼び出しの後のPOPは非常に奇妙です(そして、メモリへのポップアップは必要以上に遅いです)。また、EDIは何にも読まれないように見えるので、それは変です。私は、あなたが実際のコードが何であれ、これを切り捨てたものと仮定します。パフォーマンスのためにインラインasmでこれを書いているのであれば、おそらく最適化コンパイラより悪いです。 –

答えて

3

Windows ABIは、明らかに、charを返す関数を必要とせず、値をEAXにゼロ拡張または符号拡張するので、AL以上のバイトがガベージを保持していると仮定する必要があります。 (これはthe x86 and x86-64 System V ABIと同じです。ABI /呼び出し規約のドキュメントについてはタグwikiを参照してください)。

codify()を呼び出す前に、EAXをゼロにすることは十分であると考えることはできません。 ALでcharを返す前に、すべてのEAXをスクラッチ・レジスタとして使用するのは自由ですが、EAXの残りの部分ではごみです。

実際には、movzx esi, al(またはMOVSX)、またはmov [mem], alなど、高位バイトのゴミを無視する必要があるものがあります。

1

符号なしcharは1バイトのみで、eaxは32ビット(4バイト)のレジスタです。 codify()が1バイトのみを返す場合、戻り値は(最初のバイトはeax)に格納され、残りはeaxのまま残ります(これはごみになります)。 codify()を呼び出す前にxor eax, eaxをお勧めしますので、戻り値を格納する前にレジスタがクリーンであることがわかります。

+0

正しいアイデア、間違った実装。 codifyは、その戻り値をALに残す前に、EAX全体を一時的に使用することができます。 (私はあなたの質問にあなたのコメントに返信しようとしていたが、私が書いていたものはそれ自身で回答に変わり始めた。あなたはXORに推薦を修正しました。) –

+0

ええ;あなたが正しいことが分かります。それは 'eax'に触れることのない関数のためにのみ機能します。 –

関連する問題