[解決済み】アセンブリのtestqとcmovg命令
質問
次のことを教えてください。
testq %rdx, %rdx
cmovg %rcx, %rax
testqはビット単位で2つのレジスタの間にあることは理解できましたが、フラグについてはどのように動作するのでしょうか?
C言語ではどうなるのでしょうか?
例:もし
%rdx
は値を保持する
0x01
であれば
0x01
&です。
0x01
=
0x01
を設定することになります。
ZF = 0, SF = 0, OF = 0.
そして、私が見つけたものでは、cmovg は以下の場合に実行されます。
˜(SF ˆ OF) & ˜ZF
に解決されます。
˜(0 ˆ 0) & ˜0 = ˜(0) & ˜0 = 1 & 1 = 1.
これは、cmovgが実行され、それに対応するcコードが以下のように動作するということでしょうか。
d = %rdx
,
a = rax
と
c = rcx
:
if(d > 0){
a = c;
}
あるいは、どなたか他の言葉で説明していただけませんか?
さらに、私はこのアセンブリを対応するCコードに変換する作業を試みています。現在、私はjne .L4とtestq %rdx, %rdxで無限whileループのように終わる結果を得ます。上記のコンテンツが含まれています。どなたか、正しい解決策をご存じないでしょうか?私の現在の解決策はこれです。
p:
movq (%rdi), %rdx
testq %rdx, %rdx
je .L5
movl $0, %eax
.L4:
leaq (%rax,%rdx), %rcx
testq %rdx, %rdx
cmovg %rcx, %rax
addq $8, %rdi
movq (%rdi), %rdx
testq %rdx, %rdx
jne .L4
ret
.L5:
movl $0, %eax
ret
解答(誤)。
#include<stdlib.h>
#include <stdio.h>
int func(int *rdi){
int rdx = *rdi;
if(rdx == 0){
int rax = 0;
return rax;
}
int rax = 0;
do {
int rcx = rax + rdx;
if(rdx > 0){
rax = rcx;
}
rdi += 8;
rdx = *rdi;
} while(rdx != 0);
return rax;
}
int main(int argc, char const *argv[]) {
int var = 20;
int *ip;
ip = &var;
func(ip);
}
解決方法は?
(コメントから移動し、元の質問に返信します。)
<ブロッククオートif(d > 0){
a = c;
}
はい、正解です。以下、フラグレジスタの値を何度も計算することなく、このパターンを素早く "decode"する方法を紹介しようと思います。
<ブロッククオートお知らせ : 比較のオペランド順序が明確なため、Intelの構文が先です。 オペランドを逆にした場合 (さらに変な文字がばらまかれる)。
数値比較の条件コードは、古典的な配列の文脈で理解するのが最も適切です。
cmp a, b
jCC label
は
CC
(条件コード)の部分は、ここでいう"演算子"(のようなもの。
>
,
<
,
==
の間にあるcompareに入れていること)。
a
と
b
ということです。
-
jg
→ " j 場合a
は g よりも大きいb
となります。 -
jl
→ " j 場合a
は l よりもb
となります。 -
je
→ " j 場合a
は e クオリティーからb
となります。 -
jne
→ " j 場合a
は n オット e クオリティーb
となります。 -
ja
→ " j 場合a
は a 上b
となります。 -
jb
→ " j 場合a
は b エローb
となります。 -
... すべての "e" のバリアント (
jbe
,jae
, ...)
(上/下のカップルは、大/小のカップルと異なり、以下の点で異なります。
a
/
b
は符号なし値同士の比較用です。
g
/
l
は符号付き値で、また
多くの同義語
特に
je
の同義語です。
jz
別名ゼロ点ジャンプと呼ばれ
jne
に対して
jnz
AKA "jump if not zero"; disassemblers may produce
jz
または
je
同じです)
さて、あなたの場合ですが。
-
test reg,reg
とは完全に等価です。cmp reg,0
( の状態とは別に、AF これは簡単に理解できる。-
test
を実行します。and
をオペランド間で実行し、その結果に応じてフラグを設定します。test reg,reg
に従ってフラグを設定するだけです。reg
(and
はnop)。 -
cmp b,a
を計算します。b-a
であり,その結果に応じてフラグを設定する。b-0 == b
,cmp b,0
に従ってフラグを設定するだけです。b
と同じようにtest b,b
.
-
-
その
cmovg
のインスタンスです。cmovCC
命令で、条件コードg
の場合、移動します。 g を返します。
では、あなたの
test rdx,rdx
cmovg rax,rcx
は、以下と同等です。
cmp rdx,0
cmovg rax,rcx
これは、簡単に言うと "rdxと0を比較して、大きければraxのrcxを移動する" と読み取れます。
関連
-
[解決済み】デバッガgdbの使用時に不明な終了シグナルが発生する。
-
[解決済み】 error: too few arguments to function `printDay' (C言語)
-
[解決済み】C言語で入力が整数型かどうかチェックする
-
[解決済み】int型配列へのポインタのスカラ・イニシャライザの過剰要素
-
[解決済み】なぜか。"エラー: 配列型を持つ式への代入"
-
[解決済み】警告:式の結果が未使用の場合
-
[解決済み】シンプルなC言語のscanfが機能しない?重複
-
[解決済み] 1ビットのセット、クリア、トグルはどのように行うのですか?
-
[解決済み] const int*、const int * const、int const *の違いは何ですか?
-
[解決済み] Collatz予想の検証を行うC++のコードは、なぜ手書きのアセンブリよりも高速に動作するのでしょうか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】stdinとSTDIN_FILENOの違いは何ですか?
-
[解決済み】Cコンパイルエラー。"変数サイズのオブジェクトが初期化されていない可能性がある"
-
[解決済み】valgrind - サイズ8のブロックが割り当てられた後、アドレス ---- が0バイトになる。
-
[解決済み】式は変更可能なL値でなければならない
-
[解決済み】「構造体でもユニオンでもないものにメンバー'*******'を要求する」とはどういう意味ですか?
-
[解決済み】「複数の定義」「最初に定義されたのはここです」エラーについて
-
[解決済み] '{'トークンの前に期待される式
-
[解決済み] Cプログラムで「配列の添え字が整数でない」。
-
[解決済み】配列型char[]が代入できない [重複]。
-
[解決済み] eax に対して `testl` eax?