0

私は自分自身のx86を教えしようとしている、と私はすぐに、負の数を返す必要が渡って実行しました:私は、この関数の戻り値を印刷するときx86では64ビットのネガティブを即座にエンコードできますか?

.text 
.align 4,0x90 
.globl _scheme_entry 
_scheme_entry: 
movl $-42, %eax 
ret 

は(printf("%" PRIdPTR "\n", scheme_entry())、私が取得ナンセンス番号:それは代わりに、64ビットの、負00000000FFFFFFFF 32ビットの負だから

$ ./neg             
4294967254 

私はこれを推測しているが、FFFFFFFFFFFFFFFFある

私は定数64ビットの値を格納するにはどうすればよいです。アセンブラ機能で直接に?私は2つの別々の指示としてそれをコード化しなければならないのですか?

+0

あなたは間違ってそれを印刷していませんか? 'scheme_entry'は32ビットの整数を返すようです(そうでなければ' eax'に入れていますか?) – harold

+0

gccは通常、関数のエントリポイントを16バイトに整列します。パディングが1バイトのNOPになるように強制する理由もありません(実行されないため)。 '.p2align 4'を使って' 1 << 4'に整列させてください。 (このような小さな機能のために、8バイトの境界は関数全体をカバーするので、 '.p2align 3'とすることができます。)現代のCPUは、古いCPUほどコードの位置合わせに敏感ではありませんが、 NOP埋め込みは実行されません。そのかなりのが、私の頭の上にある –

+0

@PeterCordes - 私は[コンパイラ書き込みチュートリアル](http://scheme2006.cs.uchicago.edu/11-ghuloum.pdf)に沿って、以下のよ、意図的に私たちを持っています小さなCの入力に対して 'gcc'の出力を使ってコンパイラから何を出すかを決めます。上記のボイラープレートは、基本的にそのままコピーされていましたが、私はまだそれが何かを学んだことはありません! :x – ELLIOTTCABLE

答えて

3

32ビット命令用の32ビット命令(movlなど)の場合は32ビットの直後が使用され、writing EAX zeros the upper 32 bits of RAXの場合はそのまま使用されます。あなたはナンセンスになっていない、あなたは2^32 - 42を得ている。これは、x86が2の補数符号付き整数を使用するため、まさに期待するべきことである。 64ビットのオペランドサイズを有する命令のため

32ビット即値を64ビットに符号拡張されています。

使用mov $-42, %raxはわずか2^32以下代わりに正の64ビット値を、負の64ビット値を戻します。 (宛先として%raxを使用すると、64ビットのオペランドサイズ(つまり、movqを意味します)。

レジスタ内の値を表示するには、デバッガを使用します。

+0

これは素晴らしい情報です!はい、私は2の補数を知っていました。 '%rax'(そして' mov'と 'movl'、明らかに?)は私がここで欠けていたものでした。私はこれで実行します!ありがとうございました! – ELLIOTTCABLE

+2

@ELLIOTTCABLEむしろmovl対movq。接尾辞は、オペランドから明らかな場合は省略できます。 – fuz

関連する問題