jpnykw’s blog

軽率なアウトプットをします

x86の除算命令

x86の四則演算を行う命令は add, sub, imul, idiv の4種類ある (左から, 加算, 減算, 乗算, 除算).
ここで左3つの命令は一般的な命令と同様に, 以下のBNFを満たす.

<instruction> ::= <register> "," (<register> | <value>)

しかし idiv だけ実装が特殊で, このようなことができない.
では, 具体的に x \div y を計算する方法について書く.

どうやるの

x=14, y=7 の時について

mov rax, 14
mov rdi, 7

それぞれの値をrax, rdiレジスタに退避させる.

cqo

符号拡張を行う転送命令で, この操作によって rax の値を 128bit integer に拡張し, rax, rdi レジスタへ格納する. これは idiv の仕様上必要な工程.

idiv rdi

さて, これが問題の idiv. この命令は rdx, rax を合わせた値を 128bit integer として扱い, それを第1オペランドレジスタの 64bit 値で割る. 商を rax, 余りを rdi レジスタに格納する.

全体像

実行できる様に全体を書く.

.intel_syntax noprefix
.global main

main:
  mov rax, 14
  mov rdi, 7
  cqo
  idiv rdi
  ret

完成. こいつをコンパイルすれば2が出力されるはず. こんな感じ.

f:id:jpnykw:20200207024531p:plain

では, 良いアセンブリライフを