1. ホーム
  2. linux

[解決済み] at&tアセンブリの「push」と「pushq」の違いは何ですか?

2022-02-04 12:15:29

質問内容

最近、パソコンの仕組みをより深く理解するための探求を始めたところです。私の質問は、pushとpushqの違いについてです。

pushがスタックに値を書き込むことは知っていますが、pushqも同じようなことをすると思っています。qがあるということは、微妙な違いがあるはずだと思うのですが、どうもその違いがよくわからないのです。

gdb の 'layout asm' コマンドを使用して /lib/udev/iphone-set-info ファイルをデバッグしているときに、この質問について熟考していることを述べました。

問題のコードは:

pushq  $0x0
push   %r9

0x0は16進数でNULLを表し、%r9は一般レジスタの1つであることは理解しました。これは、NULLがスタックに書き込まれ、その上にレジスタ%r9が書き込まれるということだけでしょうか?

解決方法は?

どのようなアセンブリ言語をお使いかわかりませんが、AT&T構文を使うGAS(GNU Assembler)でも同じことが言えます。GAS のアセンブリ命令には、一般に "b", "s", "w", "l", "q", "t" という文字が付加されて、操作するオペランドのサイズを決定しています。

  • b = バイト(8ビット)
  • s = ショート(16ビット整数)またはシングル(32ビット浮動小数点)
  • w = ワード(16ビット)
  • l = long (32ビット整数または64ビット浮動小数点)
  • q = quad (64ビット)
  • t = 10バイト(80ビット浮動小数点)

サフィックスが指定されず、かつ命令に対するメモリ・オペランドが存在しない場合、GASは宛先レジスタ・オペランド(最終オペランド)のサイズからオペランド・サイズを推論します。

pushq $0x0 は 0 バイトを 8 個スタックにプッシュするだけです。そして push %r9 は、次のように定義しています。 %r9 は64ビットレジスタで、その値はスタックにプッシュされます。

スタックについて興味深い事実は、スタックは下に成長するため、ヌルバイトのアドレスは %r9 であるため、誤解が生じる可能性があります。 %r9 はヌルバイト以下です。