初心者OK!質問大歓迎!のアセンブラのスレッドです。
基本情報の勉強中の人、PICやH8を勉強中の学生などなど…
前スレ
アセンブラ初心者スレッド
http://echo.2ch.net/test/read.cgi/tech/1314502612/
関連スレ
アセンブラ 13
http://echo.2ch.net/test/read.cgi/tech/1314512680/
探検
アセンブラ初心者スレッド 2©2ch.net
レス数が900を超えています。1000を超えると表示できなくなるよ。
2017/04/13(木) 17:35:55.70ID:1WMn3pSz
837デフォルトの名無しさん
2020/08/04(火) 15:22:33.51ID:CK7AS0VE >>836
そういうことではなく、レジスタをアドレス空間にマッピングしているCPUは、
例えば、アドレス空間の 0〜255 番地の部分をレジスタ専用に
して、CPUの外部のアドレスバスには信号が出ないようにしていることが多い。
そして、
mov [0],値
と書くと、r0 に「値」を書き込むようにCPUが設計されていて、
外部のDRAMなどには全く信号が送られないようになっている。
そういうことではなく、レジスタをアドレス空間にマッピングしているCPUは、
例えば、アドレス空間の 0〜255 番地の部分をレジスタ専用に
して、CPUの外部のアドレスバスには信号が出ないようにしていることが多い。
そして、
mov [0],値
と書くと、r0 に「値」を書き込むようにCPUが設計されていて、
外部のDRAMなどには全く信号が送られないようになっている。
838デフォルトの名無しさん
2020/08/04(火) 15:30:51.43ID:z2HwYjyf >>837
そういうのもあるだろうけど、それは最初からそういう設計にしているからそう動くということだよね。
アドレス空間にある入出力領域は固定的である必要はないので、バスに出た信号をどう処理するかは
設計者が自由に決められるはず。なので、バスに出た信号をメモリだけに送ることもできるし、
CPUとメモリ両方に送ることもできる。用途に合わせればいいということかと。
そういうのもあるだろうけど、それは最初からそういう設計にしているからそう動くということだよね。
アドレス空間にある入出力領域は固定的である必要はないので、バスに出た信号をどう処理するかは
設計者が自由に決められるはず。なので、バスに出た信号をメモリだけに送ることもできるし、
CPUとメモリ両方に送ることもできる。用途に合わせればいいということかと。
839デフォルトの名無しさん
2020/08/04(火) 15:34:19.50ID:CK7AS0VE840デフォルトの名無しさん
2020/08/04(火) 16:20:06.60ID:z2HwYjyf841デフォルトの名無しさん
2020/08/04(火) 19:31:24.43ID:aUyBUHRY >>837
ああ、ずっと何の話をしてるのか分からなかったけど0ページの話ね。
ああ、ずっと何の話をしてるのか分からなかったけど0ページの話ね。
842デフォルトの名無しさん
2020/08/16(日) 16:21:04.44ID:Cqk7CoxF >>839 アルディーノのCPUがそれだ。レジスタがメモリにマッピングされている。
843デフォルトの名無しさん
2020/08/17(月) 08:09:56.01ID:tzd42ouk LLVMが吐き出したx86-64アセンブラコードを入力とするツールを作りたいのですが
このアセンブラコードの文法に関する資料って何処にあるんでしょうか
ttps://llvm.org/docs/Extensions.html
ttps://sourceware.org/binutils/docs/as/
あたりにも各命令をどのように記述するかまでは載っていないように見えるのですが・・・
このアセンブラコードの文法に関する資料って何処にあるんでしょうか
ttps://llvm.org/docs/Extensions.html
ttps://sourceware.org/binutils/docs/as/
あたりにも各命令をどのように記述するかまでは載っていないように見えるのですが・・・
844デフォルトの名無しさん
2020/08/17(月) 10:11:33.24ID:RiKJFl8Z 命令セットレベルの話ならインテルのマニュアルでも見ろとしか。
845デフォルトの名無しさん
2020/08/17(月) 11:34:25.89ID:NVTg5S9X >>843
Intelに大量の PDF マニュアルがあり、詳細に書いてある。
Intelに大量の PDF マニュアルがあり、詳細に書いてある。
846デフォルトの名無しさん
2020/08/17(月) 11:37:24.90ID:NVTg5S9X >>843
LLVMツールの出力する、native の x86 や x64 のアセンブリコードは、
試してみる限り、masm 形式ではない。
見た目はgccの形式に似ている。
LLVMのarm版が出力したnativeアセンブリコードは、gccのgasが解釈して正しくobjファイル
までアセンブルできたことがある。
x86 や x64 の場合は、そこまでは試していない。
LLVMツールの出力する、native の x86 や x64 のアセンブリコードは、
試してみる限り、masm 形式ではない。
見た目はgccの形式に似ている。
LLVMのarm版が出力したnativeアセンブリコードは、gccのgasが解釈して正しくobjファイル
までアセンブルできたことがある。
x86 や x64 の場合は、そこまでは試していない。
847843
2020/08/17(月) 12:59:34.65ID:WGW93JMF848デフォルトの名無しさん
2020/08/18(火) 01:12:29.19ID:xqTakpBf >>847
命令表記は、8バイトのオペランド(や型)を表すのにdqwordとowordで表す
2つの流儀がある。
さらに、mmwordを使う流儀もあるが、浮動小数点演算のx87の文化では
浮動小数点でも専用の型名は無くて、dwordでfloat、qwordでdoubleを扱う
流儀があった。
そこにxmmやmmxのためだけにmmwordを持ってきた意図やセンスは
賛否が分かれるところだと思う。
命令表記は、8バイトのオペランド(や型)を表すのにdqwordとowordで表す
2つの流儀がある。
さらに、mmwordを使う流儀もあるが、浮動小数点演算のx87の文化では
浮動小数点でも専用の型名は無くて、dwordでfloat、qwordでdoubleを扱う
流儀があった。
そこにxmmやmmxのためだけにmmwordを持ってきた意図やセンスは
賛否が分かれるところだと思う。
849デフォルトの名無しさん
2020/08/18(火) 01:28:37.97ID:xqTakpBf >>847
x64のリファレンスは、原則的にAMDで、AMDにも詳しいマニュアルがある。
命令表記は、絶対アドレス addr に対する間接参照で、昔は、[addr]と
表記していたものが、x64だと、マシン語レベルでは絶対アドレスを埋め込まずに、
ripからの相対アドレスrel_addrを用いて、[rip+rel_addr]のような意味になっている
があるが、アセンブラレベルでそれを表記する時、どうするかと言う問題がある。
masmだと昔から、
mov eax,MyWork1
・・・
ret
MyWork dd 1234
と書いてきた。普通のアセンブラなら、
mov eax,[MyWork1]
・・・
ret
MyWork: dd 1234
と書くところを。
しかし、rip相対になった場合、
mov eax,[rip+MyWork]
と書くと意味に合わないし、かと言って、
mov eax,[rip+rel MyWork]
と書くのも長くなる。意味的には、Masmだと
mov eax,MyWork
なのだが、マシン語レベルでは、絶対アドレス/相対アドレスのどちらで表現されるか、
明確に表すことはできなくなるジレンマがある。
x64のリファレンスは、原則的にAMDで、AMDにも詳しいマニュアルがある。
命令表記は、絶対アドレス addr に対する間接参照で、昔は、[addr]と
表記していたものが、x64だと、マシン語レベルでは絶対アドレスを埋め込まずに、
ripからの相対アドレスrel_addrを用いて、[rip+rel_addr]のような意味になっている
があるが、アセンブラレベルでそれを表記する時、どうするかと言う問題がある。
masmだと昔から、
mov eax,MyWork1
・・・
ret
MyWork dd 1234
と書いてきた。普通のアセンブラなら、
mov eax,[MyWork1]
・・・
ret
MyWork: dd 1234
と書くところを。
しかし、rip相対になった場合、
mov eax,[rip+MyWork]
と書くと意味に合わないし、かと言って、
mov eax,[rip+rel MyWork]
と書くのも長くなる。意味的には、Masmだと
mov eax,MyWork
なのだが、マシン語レベルでは、絶対アドレス/相対アドレスのどちらで表現されるか、
明確に表すことはできなくなるジレンマがある。
850デフォルトの名無しさん
2020/08/21(金) 15:25:03.93ID:EskYTmRE destにメモリを指定できる命令ってパイプラインをストールさせやすいように思うけどそんな事はないの?
x64だと
ADD r/m64,r64
みたいなの
x64だと
ADD r/m64,r64
みたいなの
851デフォルトの名無しさん
2020/08/21(金) 20:30:50.01ID:+dwilF/E 確かにストールしやすいとは言えるが影響度合いはプロセッサ次第で、そういう命令を持ったプロセッサはちゃんと考慮した設計がされている。
例えばOut of Order実行を行うプロセッサはパイプラインに結果書込み待ちをするキューを持ったステージがあって、メモリ書き込み前に後続の命令を実行可能だから単純にストールはしない。
前後の命令に依存があればストールするのはレジスタ相手でも同じことだし、命令でロードとモディファイとストアを分けても実行する内容は同じなのだから、結局はプロセッサアーキテクチャ毎に最適化が必要なことには変わりがない。
例えばOut of Order実行を行うプロセッサはパイプラインに結果書込み待ちをするキューを持ったステージがあって、メモリ書き込み前に後続の命令を実行可能だから単純にストールはしない。
前後の命令に依存があればストールするのはレジスタ相手でも同じことだし、命令でロードとモディファイとストアを分けても実行する内容は同じなのだから、結局はプロセッサアーキテクチャ毎に最適化が必要なことには変わりがない。
852デフォルトの名無しさん
2020/08/22(土) 00:25:14.47ID:Rco6UMRM インテル(R) 64 アーキテクチャーおよび IA-32 アーキテクチャー最適化リファレンス・マニュアル
を良く呼んだら書いてあったわ
> 一般的に、各命令を構成するマイクロオペレーション(μOP)の数を考慮し、単一マイク
> ロオペレーション(μOP)の命令、4 マイクロオペレーション(μOP)未満の単純な命令、
> マイクロシーケンサー ROM が必要な命令の順で優先して、命令を選択すると良い。
> 〜
> ・複数のマイクロオペレーション(μOP)からなる一連の命令を分割できない場合は、
> 同等の異なる命令シーケンスに分割する。例えば、読み出し−変更−書き込み命令は、
> 読み出し−変更命令 + ストア命令に分割すると、高速化が可能である。この手法を利
> 用すれば、新しいコードシーケンスが元のコードシーケンスより大きくなった場合で
> も、パフォーマンスが向上する。
らしいのでADD m64,r64みたいな命令はパフォーマンス上のデメリットがあるから使用を控えた方が良さそう
を良く呼んだら書いてあったわ
> 一般的に、各命令を構成するマイクロオペレーション(μOP)の数を考慮し、単一マイク
> ロオペレーション(μOP)の命令、4 マイクロオペレーション(μOP)未満の単純な命令、
> マイクロシーケンサー ROM が必要な命令の順で優先して、命令を選択すると良い。
> 〜
> ・複数のマイクロオペレーション(μOP)からなる一連の命令を分割できない場合は、
> 同等の異なる命令シーケンスに分割する。例えば、読み出し−変更−書き込み命令は、
> 読み出し−変更命令 + ストア命令に分割すると、高速化が可能である。この手法を利
> 用すれば、新しいコードシーケンスが元のコードシーケンスより大きくなった場合で
> も、パフォーマンスが向上する。
らしいのでADD m64,r64みたいな命令はパフォーマンス上のデメリットがあるから使用を控えた方が良さそう
853デフォルトの名無しさん
2020/08/29(土) 02:13:33.36ID:kcJTulzj x64命令の動作を確認するのに対話式にアセンブル&実行&レジスタの確認が出来るツールとかないかな?
各値を変えながら試行錯誤したいけどソース書いてアセンブルしてデバッガに読み込んでステップ実行してだと手間すぎる
今MULのフラグの更新動作がAMDの資料を見てもIntelの資料を見てもググってももよく判らない
各値を変えながら試行錯誤したいけどソース書いてアセンブルしてデバッガに読み込んでステップ実行してだと手間すぎる
今MULのフラグの更新動作がAMDの資料を見てもIntelの資料を見てもググってももよく判らない
854デフォルトの名無しさん
2020/08/29(土) 17:42:02.36ID:CDQjtNyx855デフォルトの名無しさん
2020/08/29(土) 18:05:14.09ID:CDQjtNyx >>853
Intel® 64 and IA-32 Architectures
Software Developer’s Manual
Volume 2A:
Instruction Set Reference, A-M
-------------------------------------------------
[MUL—Unsigned Multiply]
・・・
Flags Affected
The OF and CF flags are set to 0 if the upper half of the result is 0; otherwise, they
are set to 1. The SF, ZF, AF, and PF flags are undefined.
Intel® 64 and IA-32 Architectures
Software Developer’s Manual
Volume 2A:
Instruction Set Reference, A-M
-------------------------------------------------
[MUL—Unsigned Multiply]
・・・
Flags Affected
The OF and CF flags are set to 0 if the upper half of the result is 0; otherwise, they
are set to 1. The SF, ZF, AF, and PF flags are undefined.
856デフォルトの名無しさん
2020/08/29(土) 18:39:05.44ID:kcJTulzj >>855
その文章は確認していてAMD64のドキュメントにも
>If the upper half of the product is non-zero, the instruction sets the carry flag (CF) and overflow flag
>(OF) both to 1. Otherwise, it clears CF and OF to 0.
と似たような記述があるんだけど双方の資料に書いてある"upper half"がどの部分を示しているのか判らない
演算結果の上半分が入るDレジスタの事?
その文章は確認していてAMD64のドキュメントにも
>If the upper half of the product is non-zero, the instruction sets the carry flag (CF) and overflow flag
>(OF) both to 1. Otherwise, it clears CF and OF to 0.
と似たような記述があるんだけど双方の資料に書いてある"upper half"がどの部分を示しているのか判らない
演算結果の上半分が入るDレジスタの事?
857デフォルトの名無しさん
2020/08/29(土) 19:05:00.05ID:CGaweZC2 >>856
Intelの日本語マニュアルには処理の疑似コードが載ってる。
これによると、上半分というのは、各命令で使うレジスタサイズの上半分とわかる。
8,16,32bitそれぞれ場合によって上半分の長さが変わるのでそう書くしかない。
だから64bitの場合の上半分は上位32bitになる。
操作
IF (NumberOfOperands = 1)
THEN IF (OperandSize = 8)
THEN
AX ← AL ? SRC (* signed multiplication *)
IF AL = AX
THEN CF ← 0; OF ← 0;
ELSE CF ← 1; OF ← 1;
FI;
ELSE IF OperandSize = 16
THEN
DX:AX ← AX ? SRC (* signed multiplication *)
IF sign_extend_to_32 (AX) = DX:AX
THEN CF ← 0; OF ← 0;
ELSE CF ← 1; OF ← 1;
FI;
ELSE (* OperandSize = 32 *)
EDX:EAX ← EAX ? SRC (* signed multiplication *)
IF EAX = EDX:EAX
THEN CF ← 0; OF ← 0;
ELSE CF ← 1; OF ← 1;
FI;
FI;
Intelの日本語マニュアルには処理の疑似コードが載ってる。
これによると、上半分というのは、各命令で使うレジスタサイズの上半分とわかる。
8,16,32bitそれぞれ場合によって上半分の長さが変わるのでそう書くしかない。
だから64bitの場合の上半分は上位32bitになる。
操作
IF (NumberOfOperands = 1)
THEN IF (OperandSize = 8)
THEN
AX ← AL ? SRC (* signed multiplication *)
IF AL = AX
THEN CF ← 0; OF ← 0;
ELSE CF ← 1; OF ← 1;
FI;
ELSE IF OperandSize = 16
THEN
DX:AX ← AX ? SRC (* signed multiplication *)
IF sign_extend_to_32 (AX) = DX:AX
THEN CF ← 0; OF ← 0;
ELSE CF ← 1; OF ← 1;
FI;
ELSE (* OperandSize = 32 *)
EDX:EAX ← EAX ? SRC (* signed multiplication *)
IF EAX = EDX:EAX
THEN CF ← 0; OF ← 0;
ELSE CF ← 1; OF ← 1;
FI;
FI;
858デフォルトの名無しさん
2020/08/29(土) 19:47:52.94ID:cC8g9MrB upper half of the product だから乗算結果の上半分だ。
疑問の余地は無いと思うがな…
疑問の余地は無いと思うがな…
859蟻人間 ◆T6xkBnTXz7B0
2020/08/29(土) 20:22:30.40ID:GYyhmMZY CPU emulator Unicorn
https://www.unicorn-engine.org/
https://www.unicorn-engine.org/
860デフォルトの名無しさん
2020/08/30(日) 01:05:43.21ID:BjChy3oe IF sign_extend_to_32 (AX) = DX:AX
THEN CF ← 0; OF ← 0;
ELSE CF ← 1; OF ← 1;
FI;
これだと符号拡張したものと比較しているから、言葉による説明と違っている。
基本的に、mulは、符号無しの整数に対する掛け算なのだが。
THEN CF ← 0; OF ← 0;
ELSE CF ← 1; OF ← 1;
FI;
これだと符号拡張したものと比較しているから、言葉による説明と違っている。
基本的に、mulは、符号無しの整数に対する掛け算なのだが。
861デフォルトの名無しさん
2020/08/30(日) 01:11:49.03ID:BjChy3oe >>857
それは、mul(符号無し掛け算)ではなく、imul(符号付掛け算)の擬似コードで、
英語版でも、同じような擬似コードが書いてあり、言葉による説明は、
次のようになっている:
Flags Affected
For the one operand form of the instruction, the CF and OF flags are set when signif-
icant bits are carried into the upper half of the result and cleared when the result fits
exactly in the lower half of the result. For the two- and three-operand forms of the
instruction, the CF and OF flags are set when the result must be truncated to fit in the
destination operand size and cleared when the result fits exactly in the destination
operand size. The SF, ZF, AF, and PF flags are undefined.
それは、mul(符号無し掛け算)ではなく、imul(符号付掛け算)の擬似コードで、
英語版でも、同じような擬似コードが書いてあり、言葉による説明は、
次のようになっている:
Flags Affected
For the one operand form of the instruction, the CF and OF flags are set when signif-
icant bits are carried into the upper half of the result and cleared when the result fits
exactly in the lower half of the result. For the two- and three-operand forms of the
instruction, the CF and OF flags are set when the result must be truncated to fit in the
destination operand size and cleared when the result fits exactly in the destination
operand size. The SF, ZF, AF, and PF flags are undefined.
862デフォルトの名無しさん
2020/08/30(日) 01:22:29.16ID:BjChy3oe ちなみに、同じビット数の2つの整数の掛け算は、結果の内、掛ける前の整数の
ビット数の部分に限定した部分だけを見れば、符号付き掛け算と符号無し掛け算
で結果が変わらない。
一方、imulは、2オペランド以上のものは、結果のビット数が、掛ける前と同じ。
そして、mulは、2オペランド以上のものが用意されて無い。
これは、最初に述べた性質から、imulとmulで、2オペランド以上の場合では、
結果が変わらなくなってしまうため、imulだけで、符号無し掛け算にも対応できる
ためである。
ビット数の部分に限定した部分だけを見れば、符号付き掛け算と符号無し掛け算
で結果が変わらない。
一方、imulは、2オペランド以上のものは、結果のビット数が、掛ける前と同じ。
そして、mulは、2オペランド以上のものが用意されて無い。
これは、最初に述べた性質から、imulとmulで、2オペランド以上の場合では、
結果が変わらなくなってしまうため、imulだけで、符号無し掛け算にも対応できる
ためである。
863デフォルトの名無しさん
2020/08/30(日) 14:10:51.87ID:GgAZZaQa864デフォルトの名無しさん
2020/08/30(日) 14:26:36.90ID:EVylyaDc865デフォルトの名無しさん
2020/08/30(日) 18:38:46.61ID:Oy/VxFsh おっぱいしか目に入らん
866デフォルトの名無しさん
2020/08/31(月) 15:24:59.40ID:r6h0vUdb セクションとかも理解してくれるx64逆アセンブラとかないのかな
セクション情報やデバッグ情報をディレクティブ等でコードと一緒に出力してくれるとうれしい
セクション情報やデバッグ情報をディレクティブ等でコードと一緒に出力してくれるとうれしい
867デフォルトの名無しさん
2020/09/01(火) 10:42:01.73ID:vwihzMdy >>864
昔は子供向けのベーマガに載ってるレベル。
昔は子供向けのベーマガに載ってるレベル。
868デフォルトの名無しさん
2020/09/01(火) 17:43:15.76ID:8L3AfpS1 >>866
Linux?
Linux?
869デフォルトの名無しさん
2020/09/03(木) 12:52:56.48ID:ZDuIxl5I870デフォルトの名無しさん
2020/09/03(木) 14:20:08.59ID:cueCbpYZ871デフォルトの名無しさん
2020/09/04(金) 10:09:14.61ID:KmpQA39o >>870
今時ネット通販だろうけど本屋と同じで
たまたま近くに置いてあるのに目が止まるのが良かったりするんだけどな
パートおばさんのハンダ付け作業なんて若年化する前にほぼ中国海外にいったろう
最近は新入社員研修に後ろから二人羽織状態で手を握りながら・・
今時ネット通販だろうけど本屋と同じで
たまたま近くに置いてあるのに目が止まるのが良かったりするんだけどな
パートおばさんのハンダ付け作業なんて若年化する前にほぼ中国海外にいったろう
最近は新入社員研修に後ろから二人羽織状態で手を握りながら・・
872デフォルトの名無しさん
2020/09/06(日) 06:21:38.35ID:EKeL4GkH ドキュメント72時間で秋葉原の部品屋やってたけど
女子高生がオリジナルのペンライトを作るために来てた
女子高生がオリジナルのペンライトを作るために来てた
873デフォルトの名無しさん
2020/09/06(日) 09:40:26.46ID:TNZ7/NP8 良スレ
874デフォルトの名無しさん
2020/09/07(月) 16:54:29.21ID:0bCSYOR0875デフォルトの名無しさん
2020/09/07(月) 17:52:16.84ID:0w2E3x4d >>874
撮影用のモデルだろ、半田が付いているのは裏面だ
撮影用のモデルだろ、半田が付いているのは裏面だ
876デフォルトの名無しさん
2020/09/07(月) 18:30:23.60ID:3pB/Wjpj それ以前に火傷する
877デフォルトの名無しさん
2020/09/07(月) 18:41:49.64ID:hcXGR9uA878デフォルトの名無しさん
2020/09/07(月) 22:17:45.58ID:KQEAaFWf 半田ごてを持つ部分が間違ってるし、基盤もハンダ付けする面は上下逆だし、
さあに、こういう基盤は、最近ではかなりの部分がロボットでハンダ付けしてると
聞いている。
さあに、こういう基盤は、最近ではかなりの部分がロボットでハンダ付けしてると
聞いている。
879デフォルトの名無しさん
2020/09/07(月) 22:44:57.51ID:0w2E3x4d880デフォルトの名無しさん
2020/09/08(火) 03:25:35.85ID:jacy6RM2 何周遅れか判らんくらい激しく概出過ぎてつまらん
881デフォルトの名無しさん
2020/09/09(水) 19:36:30.15ID:HmJqfQ+A >>875
そっちにもつっこみ所あったんか…今頃知った
そっちにもつっこみ所あったんか…今頃知った
882デフォルトの名無しさん
2020/09/13(日) 00:55:43.99ID:NuGQj3YA 論理演算より、鼻筋の整形が気になって・・・
883デフォルトの名無しさん
2020/09/25(金) 21:12:03.86ID:1nrszLVg 鼻の穴にもつっこむ所あったんか…
884デフォルトの名無しさん
2020/11/02(月) 22:13:42.36ID:KqjMEGzA 775にしてはアルミ電解バリバリだな
885デフォルトの名無しさん
2020/11/19(木) 16:32:15.09ID:7GrsSxFi アセンブラからドライバを読みたいですが、どうやってしますか?
886デフォルトの名無しさん
2020/11/19(木) 20:17:00.91ID:4w1/CW5J 日本語が変
887デフォルトの名無しさん
2020/11/25(水) 09:47:14.54ID:gT5in2ls 好奇心でMS-DOS 6.2にJWasmを入れてアセンブラ入門サイトを見ながら学習しています。
大きな値を10進変換したい場合はどうすれば良いのでしょう?
DX:AX ÷ 10dがしたい。
INT21hファンクションコールでAH=36hを実行してAX * BX * CXした結果を
DIV 10するのに、商が16ビットを超えるので例外が発生する。
入門中なので、2バイトまでの環境しか使い方がわかりません。
4バイトのレジスタが使えれば解決する話なのかも知れませんけど、、
DX:AXから計算する方法ないか調べています。
結局、EDX:EAXを10dで割る事になっても同じことが起きるので
大きな値を10進変換したい場合はどうすれば良いのでしょう?
DX:AX ÷ 10dがしたい。
INT21hファンクションコールでAH=36hを実行してAX * BX * CXした結果を
DIV 10するのに、商が16ビットを超えるので例外が発生する。
入門中なので、2バイトまでの環境しか使い方がわかりません。
4バイトのレジスタが使えれば解決する話なのかも知れませんけど、、
DX:AXから計算する方法ないか調べています。
結局、EDX:EAXを10dで割る事になっても同じことが起きるので
888デフォルトの名無しさん
2020/11/25(水) 12:44:21.97ID:jzvQX9aE >>887
(1)まず、DXを10で割る。
その時の商をQ1(ax),余りをR1(dx)とする。
(2)
mov ax,元のAX
xor dx,dx ;← dx=0
add ax,R1
adc dx,0
とする。これは、元のAXにR1を足したものを(dx:ax)に入れていることに相当する。
(3)
(dx:ax)を10で割り、商をQ2(ax)、余りをR2(dx)とする。
(4) 最終的な商Qは、(Q1:Q2), 余りRは、R2である。
(1)まず、DXを10で割る。
その時の商をQ1(ax),余りをR1(dx)とする。
(2)
mov ax,元のAX
xor dx,dx ;← dx=0
add ax,R1
adc dx,0
とする。これは、元のAXにR1を足したものを(dx:ax)に入れていることに相当する。
(3)
(dx:ax)を10で割り、商をQ2(ax)、余りをR2(dx)とする。
(4) 最終的な商Qは、(Q1:Q2), 余りRは、R2である。
889デフォルトの名無しさん
2020/11/25(水) 12:46:48.67ID:jzvQX9aE890デフォルトの名無しさん
2020/11/25(水) 12:50:41.35ID:jzvQX9aE コードに直すとこうなると思う。
;入力: (dx:ax)
;出力: (Q1:ax)=商, 余り=dx
mov original_ax,ax
mov ax,dx
xor dx,dx
mov cx,10
div cx
mov Q1,ax
mov ax,original_ax
div cx
;商=(Q1:ax), 余り=dx
ret
;入力: (dx:ax)
;出力: (Q1:ax)=商, 余り=dx
mov original_ax,ax
mov ax,dx
xor dx,dx
mov cx,10
div cx
mov Q1,ax
mov ax,original_ax
div cx
;商=(Q1:ax), 余り=dx
ret
891デフォルトの名無しさん
2020/11/25(水) 13:07:31.94ID:jzvQX9aE >>887
32BIT(4バイト)命令を使っていいなら、(dx:ax)/10 は、
shl edx,16
mov dx,ax
mov eax,edx
xor edx,edx
mov ecx,10
idiv ecx
で、eax に32BITの商、edx に余り(0〜9)が出る。
32BIT(4バイト)命令を使っていいなら、(dx:ax)/10 は、
shl edx,16
mov dx,ax
mov eax,edx
xor edx,edx
mov ecx,10
idiv ecx
で、eax に32BITの商、edx に余り(0〜9)が出る。
892デフォルトの名無しさん
2020/11/25(水) 13:12:20.82ID:jzvQX9aE >>891
idivじゃなくて、divが正しい。
idivじゃなくて、divが正しい。
893デフォルトの名無しさん
2020/11/25(水) 14:53:28.45ID:h9isg/D4 定数の除算に糞遅いDIV命令を使うとか
894デフォルトの名無しさん
2020/11/25(水) 14:55:43.27ID:gT5in2ls MUL BX
MUL CX
MOV Q2, DX
MOV Q1, AX
MOV BX, 10
DIV_LOOP:
XOR DX, DX
MOV AX, Q2
DIV BX
MOV Q2, AX
MOV AX, Q1
DIV BX
MOV Q1, AX
ADD DX, '0'
PUSH DX
OR AX, AX
JNZ DIV_LOOP
こんな感じですか?
気になったのですが、MOV DX, 0ではなくて、XOR DX, DXなのは処理が速いから?
CMP AX, 0よりも、OR AX, AXの方が良いのでしょうか?
MUL CX
MOV Q2, DX
MOV Q1, AX
MOV BX, 10
DIV_LOOP:
XOR DX, DX
MOV AX, Q2
DIV BX
MOV Q2, AX
MOV AX, Q1
DIV BX
MOV Q1, AX
ADD DX, '0'
PUSH DX
OR AX, AX
JNZ DIV_LOOP
こんな感じですか?
気になったのですが、MOV DX, 0ではなくて、XOR DX, DXなのは処理が速いから?
CMP AX, 0よりも、OR AX, AXの方が良いのでしょうか?
895デフォルトの名無しさん
2020/11/25(水) 15:47:06.05ID:T5VOSp5s 速いから
ではないでしょ
ではないでしょ
896デフォルトの名無しさん
2020/11/25(水) 16:46:45.83ID:jzvQX9aE >>894
>気になったのですが、MOV DX, 0ではなくて、XOR DX, DXなのは処理が速いから?
>CMP AX, 0よりも、OR AX, AXの方が良いのでしょうか?
昔は速かったので今でも伝統的に0を代入する変わりにxor reg,regを
使い、cmp ax,0の変わりに or ax,axを使う人が多い。
しかし、その「昔」とは、80486とかよりもずっと昔の初代8086の時代のことかもしれない。
ただし、xor reg,regだとフラグ類まで初期化されてしまうので、mov reg,0を使った方が
良い場合がある。
>>895
今は速くは無いが、昔は速かった。
その伝統が何故か今でも継承されている。
>気になったのですが、MOV DX, 0ではなくて、XOR DX, DXなのは処理が速いから?
>CMP AX, 0よりも、OR AX, AXの方が良いのでしょうか?
昔は速かったので今でも伝統的に0を代入する変わりにxor reg,regを
使い、cmp ax,0の変わりに or ax,axを使う人が多い。
しかし、その「昔」とは、80486とかよりもずっと昔の初代8086の時代のことかもしれない。
ただし、xor reg,regだとフラグ類まで初期化されてしまうので、mov reg,0を使った方が
良い場合がある。
>>895
今は速くは無いが、昔は速かった。
その伝統が何故か今でも継承されている。
897デフォルトの名無しさん
2020/11/25(水) 16:58:10.99ID:jzvQX9aE >>894
冒頭の
MUL BX
MUL CX
の部分が怪しい。一行目で結果がDX:AXに入っているのに、二行目ではそれを
無視しているが、無視してはいけない。
また、最後の
OR AX, AX
JNZ DIV_LOOP
の判定は間違い。
これだと、Q2がまだ非0の場合にもループが終わってしまう。
ちゃんと、Q2が非0の場合もループを続行しなくてはならない。
また、Qは、商(quotient)の頭文字を使っただけで、伝統的には、
意味が余り分からない変数は、work1 などを使う慣例があったりする。
意味が分かる場合には、意味が分かるような変数名にする。
冒頭の
MUL BX
MUL CX
の部分が怪しい。一行目で結果がDX:AXに入っているのに、二行目ではそれを
無視しているが、無視してはいけない。
また、最後の
OR AX, AX
JNZ DIV_LOOP
の判定は間違い。
これだと、Q2がまだ非0の場合にもループが終わってしまう。
ちゃんと、Q2が非0の場合もループを続行しなくてはならない。
また、Qは、商(quotient)の頭文字を使っただけで、伝統的には、
意味が余り分からない変数は、work1 などを使う慣例があったりする。
意味が分かる場合には、意味が分かるような変数名にする。
898デフォルトの名無しさん
2020/11/25(水) 17:02:18.40ID:jzvQX9aE なお、Q1は、説明の都合上、数学と似た感覚で短い変数を付けたが、
アセンブラなどに書く場合には、もっと長い名前にした方がいい。
短いとアセンブラが何かと混同して問題になるかも知れないから。
例えば、レジスタ名にr1などというものがある場合があるので注意。
アセンブラなどに書く場合には、もっと長い名前にした方がいい。
短いとアセンブラが何かと混同して問題になるかも知れないから。
例えば、レジスタ名にr1などというものがある場合があるので注意。
899デフォルトの名無しさん
2020/11/25(水) 17:44:43.84ID:h9isg/D4900デフォルトの名無しさん
2020/11/26(木) 00:21:00.79ID:5BVCYzUa 皆知ってるてのになw
901デフォルトの名無しさん
2020/11/26(木) 01:11:06.89ID:lH6B10sG >>899
では、現在のIntelCPUにおいて、
・mov reg,0の代わりにxor reg,reg
・cmp eax,0の変わりにor eax,eax
を使うメリットをそれぞれ書いてみてください。
では、現在のIntelCPUにおいて、
・mov reg,0の代わりにxor reg,reg
・cmp eax,0の変わりにor eax,eax
を使うメリットをそれぞれ書いてみてください。
902デフォルトの名無しさん
2020/11/26(木) 12:23:04.16ID:kAbnbrOP # mk_src.rb
def mk_src( md, loop1 = 1000000, loop2 = 1000 )
tit, fpath, asm_str = case md
when 1; [ 'imd', 'imd.c', %Q{\t\tasm( "movl $0, %eax\\ncmpl $0, %eax" );\n} ]
when 2; [ 'reg', 'reg.c', %Q{\t\tasm( "xorl %eax, %eax\\norl %eax, %eax" );\n} ]
end
File.open( fpath, 'w:UTF-8' ){|fh|
fh.print <<_EOT_
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
int main(void)
{
LARGE_INTEGER qpff, qpf0, qpf1;
QueryPerformanceFrequency( &qpff );
unsigned int n = #{loop2};
QueryPerformanceCounter( &qpf0 );
while( n-- ){
#{asm_str * loop1}
}
QueryPerformanceCounter( &qpf1 );
printf( " #{tit}. time %lf[ms]\\n", (double)(qpf1.QuadPart - qpf0.QuadPart) * 1000.0 / qpff.QuadPart );
return 0;
}
_EOT_
} # File.open
end
mk_src( 1 )
mk_src( 2 )
def mk_src( md, loop1 = 1000000, loop2 = 1000 )
tit, fpath, asm_str = case md
when 1; [ 'imd', 'imd.c', %Q{\t\tasm( "movl $0, %eax\\ncmpl $0, %eax" );\n} ]
when 2; [ 'reg', 'reg.c', %Q{\t\tasm( "xorl %eax, %eax\\norl %eax, %eax" );\n} ]
end
File.open( fpath, 'w:UTF-8' ){|fh|
fh.print <<_EOT_
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
int main(void)
{
LARGE_INTEGER qpff, qpf0, qpf1;
QueryPerformanceFrequency( &qpff );
unsigned int n = #{loop2};
QueryPerformanceCounter( &qpf0 );
while( n-- ){
#{asm_str * loop1}
}
QueryPerformanceCounter( &qpf1 );
printf( " #{tit}. time %lf[ms]\\n", (double)(qpf1.QuadPart - qpf0.QuadPart) * 1000.0 / qpff.QuadPart );
return 0;
}
_EOT_
} # File.open
end
mk_src( 1 )
mk_src( 2 )
903デフォルトの名無しさん
2020/11/26(木) 12:23:28.07ID:kAbnbrOP $ uname -srvmo
MINGW64_NT-10.0-18363 3.1.7-340.x86_64 2020-09-22 20:54 UTC x86_64 Msys
$ gcc imd.c -O0 -o imd; gcc reg.c -O0 -o reg
8291652 imd.exe
6291780 reg.exe
$ ./imd.exe; ./imd.exe; ./imd.exe; ./imd.exe
imd. time 221.844800[ms]
imd. time 236.904100[ms]
imd. time 205.867200[ms]
imd. time 242.199800[ms]
$ ./reg.exe; ./reg.exe; ./reg.exe; ./reg.exe
reg. time 134.806000[ms]
reg. time 145.542900[ms]
reg. time 147.039100[ms]
reg. time 143.031100[ms]
MINGW64_NT-10.0-18363 3.1.7-340.x86_64 2020-09-22 20:54 UTC x86_64 Msys
$ gcc imd.c -O0 -o imd; gcc reg.c -O0 -o reg
8291652 imd.exe
6291780 reg.exe
$ ./imd.exe; ./imd.exe; ./imd.exe; ./imd.exe
imd. time 221.844800[ms]
imd. time 236.904100[ms]
imd. time 205.867200[ms]
imd. time 242.199800[ms]
$ ./reg.exe; ./reg.exe; ./reg.exe; ./reg.exe
reg. time 134.806000[ms]
reg. time 145.542900[ms]
reg. time 147.039100[ms]
reg. time 143.031100[ms]
904デフォルトの名無しさん
2020/11/26(木) 12:58:51.67ID:lH6B10sG Intelの最適化マニュアルを見たが、or,xor,cmp,movのlatencyやthroughputは
CPUによりマチマチで、絶対にどれが速いと言うようなことはいえないと思う。
ややこしいのは、movは、latencyが1や0.5, throughoutが0.5なのに対し、
xorは、latencyが1, throughtputが0.33や0.5となっていたりする。
これもCPUIDによってさまざま。
表の中のCPUIDの表記法も独特なので、どれが最新のCPUに対応しているのかも
個人的には今のところ分からない。
CPUによりマチマチで、絶対にどれが速いと言うようなことはいえないと思う。
ややこしいのは、movは、latencyが1や0.5, throughoutが0.5なのに対し、
xorは、latencyが1, throughtputが0.33や0.5となっていたりする。
これもCPUIDによってさまざま。
表の中のCPUIDの表記法も独特なので、どれが最新のCPUに対応しているのかも
個人的には今のところ分からない。
905デフォルトの名無しさん
2020/11/26(木) 13:10:05.83ID:Ndl69lfH906デフォルトの名無しさん
2020/11/26(木) 14:55:11.18ID:l8W6EZba 馬鹿ほど脳みそ足りないからAppleのようにすぐ互換性を捨てたがる。
そんな馬鹿は伝統を重んじてきたx86系を使わないでほしい。
そんな馬鹿は伝統を重んじてきたx86系を使わないでほしい。
907デフォルトの名無しさん
2020/11/26(木) 16:30:36.87ID:s+oX3EtE908デフォルトの名無しさん
2020/11/26(木) 18:31:44.20ID:b0/J9kY8 命令自体のクロック数は多少違うかもしれんがキャッシュ効率も考えれば1バイト命令のxor ax,axの方が正解の確率が高いと思うよ。
909デフォルトの名無しさん
2020/11/26(木) 18:39:31.62ID:rqBz/pid てかxor reg, regはIntelやAMDの最適化マニュアルにも書いてあるくらいなんだが
910デフォルトの名無しさん
2020/11/26(木) 18:48:11.36ID:HK02mgb4 x86は386,486,586,686と拡張されてきて、その度に命令が拡張されてきてる。これらはどれもx86だが、
これらの互換性を取ろうとすると386に合わせるしかなくなる。しかしそれでは今のWindowsは動かない。
一般の人にとって互換性というのは普段使っているアプリケーションが動けばいいので、それでほぼ支障ない。
最近のIntel CPUはHaswell、Broadwell、Skylake、Kebylakeと来ているが、これらの間だけ見ても
命令が拡張されているので完全な互換性はない。ならば互換性を重視して、最新CPUの便利な機能を使うな
ということになると技術者のレベルは昔のまま上がらないことになる。それは時代に取り残されることにならないか。
386はシングルコアだったが今はマルチコアが当たり前の時代だ。しかしソフトウェアは今でもシングルコアを
前提に書くことが多い。その方が簡単だしそれでも動くからだ。しかし、搭載されているコア数を最初に見て、
マルチコアだったら並列処理できるところは並列で動かせば早くなるのがわかっていても。互換性のために
わざとそうしないとしたらそれはただの怠慢に過ぎないだろう。そういう人はx86系を使わないでほしい。
これらの互換性を取ろうとすると386に合わせるしかなくなる。しかしそれでは今のWindowsは動かない。
一般の人にとって互換性というのは普段使っているアプリケーションが動けばいいので、それでほぼ支障ない。
最近のIntel CPUはHaswell、Broadwell、Skylake、Kebylakeと来ているが、これらの間だけ見ても
命令が拡張されているので完全な互換性はない。ならば互換性を重視して、最新CPUの便利な機能を使うな
ということになると技術者のレベルは昔のまま上がらないことになる。それは時代に取り残されることにならないか。
386はシングルコアだったが今はマルチコアが当たり前の時代だ。しかしソフトウェアは今でもシングルコアを
前提に書くことが多い。その方が簡単だしそれでも動くからだ。しかし、搭載されているコア数を最初に見て、
マルチコアだったら並列処理できるところは並列で動かせば早くなるのがわかっていても。互換性のために
わざとそうしないとしたらそれはただの怠慢に過ぎないだろう。そういう人はx86系を使わないでほしい。
911デフォルトの名無しさん
2020/11/26(木) 18:55:48.10ID:l8W6EZba このように互換性捨てろという奴は頭悪いとよく分かる。
PowerPC、IA64、MIPSから何も学んでないのだ。
PowerPC、IA64、MIPSから何も学んでないのだ。
912デフォルトの名無しさん
2020/11/26(木) 19:02:03.76ID:rqBz/pid x86を捨てたがっているのはIntel自身なんだよなぁ
913デフォルトの名無しさん
2020/11/26(木) 19:40:42.10ID:lH6B10sG914デフォルトの名無しさん
2020/11/26(木) 19:52:22.98ID:lH6B10sG >>909
今見てみたら、xor reg,reg や sub reg,reg には「実行依存性」を断ち切る効果が
あると書いてあった。Pentium 4 から特別な扱いをする様になったとか。
つまり、xor reg,regだとフラグまで初期化してしまうので、フラグが決まるまで
Latencyを待つ必要が無い。
ところが、mov reg,0だとフラグは引き継ぐから前の命令によってフラグが
決まるまで次の命令の実行が待たされることがあるのかな。
もしかしたら、CPU内部では、ZF,CF,SFなどと独立して変更できずに、
EFLAGS全体を1つのレジスタの様に扱うことが基本になっていて、
一部だけを変更しようとすると待機が発生しやすくなるのかもしれない。
今見てみたら、xor reg,reg や sub reg,reg には「実行依存性」を断ち切る効果が
あると書いてあった。Pentium 4 から特別な扱いをする様になったとか。
つまり、xor reg,regだとフラグまで初期化してしまうので、フラグが決まるまで
Latencyを待つ必要が無い。
ところが、mov reg,0だとフラグは引き継ぐから前の命令によってフラグが
決まるまで次の命令の実行が待たされることがあるのかな。
もしかしたら、CPU内部では、ZF,CF,SFなどと独立して変更できずに、
EFLAGS全体を1つのレジスタの様に扱うことが基本になっていて、
一部だけを変更しようとすると待機が発生しやすくなるのかもしれない。
915デフォルトの名無しさん
2020/11/26(木) 19:56:51.64ID:lH6B10sG >>914
スマン。
そういう意味ではないようだわ。
or eax,ebx
とかだと、直前までの命令でeaxとebxの両方のレジスタの値が決まってないと
パイプライン上でこの命令ALUのステージを実行することは出来ないので待機が
発生する。
ところが、xor eax,eax だと直前までの命令のeaxの結果がどうであれ、この
命令は必ずeaxを0にしてしまうから、待機する必要が無い、という意味だった。
スマン。
そういう意味ではないようだわ。
or eax,ebx
とかだと、直前までの命令でeaxとebxの両方のレジスタの値が決まってないと
パイプライン上でこの命令ALUのステージを実行することは出来ないので待機が
発生する。
ところが、xor eax,eax だと直前までの命令のeaxの結果がどうであれ、この
命令は必ずeaxを0にしてしまうから、待機する必要が無い、という意味だった。
916デフォルトの名無しさん
2020/11/26(木) 20:18:29.14ID:l8W6EZba コード長はくだらん揚げ足取りに見える。普通にオペランドも入れて解釈すべきでキャッシュ効率は不利。
昔からレジスタ初期化で多用されるxorは組み合わせ回路、ワイヤードロジック一発で多くのCPUでも特別扱い。
XOR r32, r32 L: 0.07ns= 0.2c T: 0.07ns= 0.24c
OR r32, r32 L: 0.29ns= 1.0c T: 0.07ns= 0.25c
AND r32, r32 L: 0.29ns= 1.0c T: 0.10ns= 0.33c
昔からレジスタ初期化で多用されるxorは組み合わせ回路、ワイヤードロジック一発で多くのCPUでも特別扱い。
XOR r32, r32 L: 0.07ns= 0.2c T: 0.07ns= 0.24c
OR r32, r32 L: 0.29ns= 1.0c T: 0.07ns= 0.25c
AND r32, r32 L: 0.29ns= 1.0c T: 0.10ns= 0.33c
917デフォルトの名無しさん
2020/11/26(木) 20:42:01.46ID:l8W6EZba よく使う命令を重点的にトランジスタを大量投入して速くしようというのはコードの互換性を大事にしてるからの発想。古いコードでも速く動かしてやるという努力の賜物のx86。
一方、使わない命令は削除、もう頭使うのが嫌だからと最適化はコンパイラの仕事と最適化を放り出して衰退したRISC哲学。
一方、使わない命令は削除、もう頭使うのが嫌だからと最適化はコンパイラの仕事と最適化を放り出して衰退したRISC哲学。
918デフォルトの名無しさん
2020/11/26(木) 20:43:40.28ID:lH6B10sG >>916
mov reg,0
は、オペランドも全て含めて2バイト。
0は、short formで8BITオペランドになるから。
xor reg,regは、immオペランドが無くても2バイト。
なぜなら、movは、特別な短いマシン語が割り当てられているのに、xorは
そうではないから。
mov reg,0
は、オペランドも全て含めて2バイト。
0は、short formで8BITオペランドになるから。
xor reg,regは、immオペランドが無くても2バイト。
なぜなら、movは、特別な短いマシン語が割り当てられているのに、xorは
そうではないから。
919デフォルトの名無しさん
2020/11/26(木) 20:50:33.32ID:weG7Hi1V タブ機能付きのソフト(AcrobatReaderとかテキストエディターとか)の現在アクティブな
タブのファイルパスのアドレスを調べたいんですけど、めちゃめちゃ頑張ったんですけど無理でした。
わかったことは、AcrobatReaderの場合、開いた順にインデックスが振られて(初めの値は0
ではなく1)、アクティブタブのインデックスが格納されたアドレスがあるということです。
もしくはインデックスが振られるのではなく、ファイルパスを開いた順に配列にプッシュして
ファイルパス配列[アクティブタブのインデックス - 1] のタブをアクティブにしろという命令が出てる。
前者の場合、インデックスが格納されてるアドレスがどこかさっぱりわかんなくって、ファイルパス
のアドレスからちょっと前をみたりマックスパスの260Byte後ろのとこを見たりしたんですけど
それらしきインデックスが見つかりませぬ。
それで、ファイルパスにアクセスしてる関数を見たんですけどアセンブリ言語サッパリ( 一一)
どなたか助言お願いします。
ファイルパスにアクセスしてるらしき関数↓
AcroRd32.dll+4637E - 33 D2 - xor edx,edx
AcroRd32.dll+46380 - 8B C1 - mov eax,ecx
AcroRd32.dll+46382 - 66 39 11 - cmp [ecx],dx
AcroRd32.dll+46385 - 74 08 - je AcroRd32.dll+4638F
AcroRd32.dll+46387 - 83 C0 02 - add eax,02 { 2 }
AcroRd32.dll+4638A - 66 39 10 - cmp [eax],dx
AcroRd32.dll+4638D - 75 F8 - jne AcroRd32.dll+46387
AcroRd32.dll+4638F - 2B C1 - sub eax,ecx
AcroRd32.dll+46391 - D1 F8 - sar eax,1
AcroRd32.dll+46393 - 5D - pop ebp
AcroRd32.dll+46394 - C3 - ret
もう1週間くらい頑張ってます。宜しくお願いします。
タブのファイルパスのアドレスを調べたいんですけど、めちゃめちゃ頑張ったんですけど無理でした。
わかったことは、AcrobatReaderの場合、開いた順にインデックスが振られて(初めの値は0
ではなく1)、アクティブタブのインデックスが格納されたアドレスがあるということです。
もしくはインデックスが振られるのではなく、ファイルパスを開いた順に配列にプッシュして
ファイルパス配列[アクティブタブのインデックス - 1] のタブをアクティブにしろという命令が出てる。
前者の場合、インデックスが格納されてるアドレスがどこかさっぱりわかんなくって、ファイルパス
のアドレスからちょっと前をみたりマックスパスの260Byte後ろのとこを見たりしたんですけど
それらしきインデックスが見つかりませぬ。
それで、ファイルパスにアクセスしてる関数を見たんですけどアセンブリ言語サッパリ( 一一)
どなたか助言お願いします。
ファイルパスにアクセスしてるらしき関数↓
AcroRd32.dll+4637E - 33 D2 - xor edx,edx
AcroRd32.dll+46380 - 8B C1 - mov eax,ecx
AcroRd32.dll+46382 - 66 39 11 - cmp [ecx],dx
AcroRd32.dll+46385 - 74 08 - je AcroRd32.dll+4638F
AcroRd32.dll+46387 - 83 C0 02 - add eax,02 { 2 }
AcroRd32.dll+4638A - 66 39 10 - cmp [eax],dx
AcroRd32.dll+4638D - 75 F8 - jne AcroRd32.dll+46387
AcroRd32.dll+4638F - 2B C1 - sub eax,ecx
AcroRd32.dll+46391 - D1 F8 - sar eax,1
AcroRd32.dll+46393 - 5D - pop ebp
AcroRd32.dll+46394 - C3 - ret
もう1週間くらい頑張ってます。宜しくお願いします。
920デフォルトの名無しさん
2020/11/27(金) 00:50:22.02ID:dazyxaWu >>918
ならないな。バイナリ出して。
0100 mov ax,0
0103 xor ax,ax
0100 B8 00 00 31 C0
B8 00 00 00 00 mov eax,0
33 C0 xor eax,eax
ならないな。バイナリ出して。
0100 mov ax,0
0103 xor ax,ax
0100 B8 00 00 31 C0
B8 00 00 00 00 mov eax,0
33 C0 xor eax,eax
921デフォルトの名無しさん
2020/11/27(金) 00:56:36.27ID:lOUpIwv2 OllyDbg などの逆アセンブラツールを使えないのか?
922デフォルトの名無しさん
2020/11/27(金) 14:37:53.57ID:35rurNSb >>919
何をしたいのかが分からないが、例えばVS2019にAcrobatReaderの*.exeファイルを
ドラッグアンドドロップして、デバッグを開始し、タブにファイルを開いた状態にする。
そこでデバッガによりアプリを停止させて、メモリー内でそのファイル名を検索する。
どうやって検索すればよいかは良く知らない。
VS2019ではなく、OllyDbgなどを使えばよいかもしれない。
それでファイル名が入っているメモリーアドレスは分かることは分かる。
もう一つは、ファイルをオープンする場合、必ず Win32 の CreateFile APIが呼び出される
ので、CreateFileの 関数アドレスにブレイクポイントを仕掛ける。
その状態で実行すると何回かブレイクしているうち、タブのファイル名に対して
CreateFileが呼び出されることがあるはず。
その状態になったら、コールスタック(呼び出し履歴)を辿って、CreateFileを
呼び出している場所を見つける。そうすると、ファイル名を渡しているコードが
見つかる。
何をしたいのかが分からないが、例えばVS2019にAcrobatReaderの*.exeファイルを
ドラッグアンドドロップして、デバッグを開始し、タブにファイルを開いた状態にする。
そこでデバッガによりアプリを停止させて、メモリー内でそのファイル名を検索する。
どうやって検索すればよいかは良く知らない。
VS2019ではなく、OllyDbgなどを使えばよいかもしれない。
それでファイル名が入っているメモリーアドレスは分かることは分かる。
もう一つは、ファイルをオープンする場合、必ず Win32 の CreateFile APIが呼び出される
ので、CreateFileの 関数アドレスにブレイクポイントを仕掛ける。
その状態で実行すると何回かブレイクしているうち、タブのファイル名に対して
CreateFileが呼び出されることがあるはず。
その状態になったら、コールスタック(呼び出し履歴)を辿って、CreateFileを
呼び出している場所を見つける。そうすると、ファイル名を渡しているコードが
見つかる。
923デフォルトの名無しさん
2020/11/27(金) 14:42:33.59ID:35rurNSb >>922
なお、ファイルパスの入っているアドレスは分かる様になるが、
当然、アドレスは毎回変化するので、果たして何をしたいか、ということになる。
ファイルパスを入れているメモリーブロックを malloc や new している
コードを探すことは出来るかもしれないし、そのアドレスをどこかに格納している
コードも探すことは可能かも知れない。
が、複雑すぎて、そこで得た知見で何かをするということは
アセンブラに最高に詳しい人でもかなり難しい。
なお、ファイルパスの入っているアドレスは分かる様になるが、
当然、アドレスは毎回変化するので、果たして何をしたいか、ということになる。
ファイルパスを入れているメモリーブロックを malloc や new している
コードを探すことは出来るかもしれないし、そのアドレスをどこかに格納している
コードも探すことは可能かも知れない。
が、複雑すぎて、そこで得た知見で何かをするということは
アセンブラに最高に詳しい人でもかなり難しい。
924デフォルトの名無しさん
2020/11/27(金) 14:47:20.40ID:35rurNSb >>923
例えば、OllyDbgなどを使えば、ファイルパスが入っているメモリーアドレスを
検索して探し出すことは出来るかも知れない。
それで見つかったアドレスを X とする。
今度は、そのアドレス X を格納しているメモリーを探すこともできることはできる
可能性がある。
その場合、little endian なので、バイトレベルでは下位バイトから上位バイトに
向かって格納されていることに注意する。
ただし、アドレスXが格納されているアドレスは、複数見つかる可能性がある。
また、X そのものではなく、X より少し小さいアドレスが格納されていることもありえる。
だから、このような解析は難しいものとなる。
またこのような方法以外に、dumpbin に /disasm オプションをつけて Acrobat の *.exeを
逆アセンブルした結果を併用するのが基本。
例えば、OllyDbgなどを使えば、ファイルパスが入っているメモリーアドレスを
検索して探し出すことは出来るかも知れない。
それで見つかったアドレスを X とする。
今度は、そのアドレス X を格納しているメモリーを探すこともできることはできる
可能性がある。
その場合、little endian なので、バイトレベルでは下位バイトから上位バイトに
向かって格納されていることに注意する。
ただし、アドレスXが格納されているアドレスは、複数見つかる可能性がある。
また、X そのものではなく、X より少し小さいアドレスが格納されていることもありえる。
だから、このような解析は難しいものとなる。
またこのような方法以外に、dumpbin に /disasm オプションをつけて Acrobat の *.exeを
逆アセンブルした結果を併用するのが基本。
925デフォルトの名無しさん
2020/11/27(金) 14:53:31.46ID:35rurNSb >>924
そのような方法で粘り強く解析していくと、dumpbinの逆アセンブルコードの
どのあたりで、ファイルパスを格納するメモリーを確保し、そのアドレスを
どこかに記録しているコードは見つかる可能性は有る。
ただし、問題はそう簡単ではなく、「どこかに記録している」の「どこか」
がまた、毎回アドレスが変わることにある。
C/C++で言えば、非常に多数の構造体が連鎖的にリンクされているから。
このくらいの規模のアプリだと、その連鎖は、10以上になることは少なくない。
連鎖の仕方もif分などで場合分けされていて、条件によって複雑に代わりうる。
ソースコードがあっても複雑すぎてなにをやっているかを理解することはとても
困難。だから、ソースコードが無い状態でそれを理解することはとてつもなく
難しい。
そのような方法で粘り強く解析していくと、dumpbinの逆アセンブルコードの
どのあたりで、ファイルパスを格納するメモリーを確保し、そのアドレスを
どこかに記録しているコードは見つかる可能性は有る。
ただし、問題はそう簡単ではなく、「どこかに記録している」の「どこか」
がまた、毎回アドレスが変わることにある。
C/C++で言えば、非常に多数の構造体が連鎖的にリンクされているから。
このくらいの規模のアプリだと、その連鎖は、10以上になることは少なくない。
連鎖の仕方もif分などで場合分けされていて、条件によって複雑に代わりうる。
ソースコードがあっても複雑すぎてなにをやっているかを理解することはとても
困難。だから、ソースコードが無い状態でそれを理解することはとてつもなく
難しい。
926デフォルトの名無しさん
2020/11/27(金) 19:42:52.50ID:ljdbT47c でも有能なハッカーはそれを解読するよね
927デフォルトの名無しさん
2020/11/27(金) 22:46:27.98ID:ULLAjR/s >>926
お前さんは有能なハッカーですか?
お前さんは有能なハッカーですか?
928デフォルトの名無しさん
2020/11/28(土) 00:05:40.76ID:OUdaBd4w >>926
ハッカーは、ハッキングに関係ないことは何もやらないでしょう
ハッカーは、ハッキングに関係ないことは何もやらないでしょう
929デフォルトの名無しさん
2020/11/28(土) 00:34:33.70ID:qjEapHwo > mov reg,0
> は、オペランドも全て含めて2バイト。
> 0は、short formで8BITオペランドになるから。
これって本当なの? そうアセンブルされないけど。
> は、オペランドも全て含めて2バイト。
> 0は、short formで8BITオペランドになるから。
これって本当なの? そうアセンブルされないけど。
930デフォルトの名無しさん
2020/11/28(土) 17:46:27.32ID:WIRcuTWz931デフォルトの名無しさん
2020/11/28(土) 20:17:09.98ID:qjEapHwo アスペなの? ボクのCPUの話じゃなく、
本人はz80ではなくx86だと言ってるからx86の話を聞いているんだよ。
他社の互換含めてx86系CPUが一体どれだけあると思ってるの? 全部確認できるわけないじゃん。
本人はz80ではなくx86だと言ってるからx86の話を聞いているんだよ。
他社の互換含めてx86系CPUが一体どれだけあると思ってるの? 全部確認できるわけないじゃん。
932デフォルトの名無しさん
2020/11/28(土) 20:21:31.70ID:kjtXSxRe >>919
です!!>>922 さんありがとうございました!
なんとアクティブタブのファイルパスアドレス見つかりました!
AHKですけど、よかったら皆さんこの関数使ってください!
;==================================================
JEE_GetAcroRd32Path(hWnd)
{
WinGetClass, vWinClass, % "ahk_id " hWnd
if !(vWinClass = "AcrobatSDIWindow")
return
WinGet, vPID, PID, % "ahk_id " hWnd
WinGet, vPPath, ProcessPath, % "ahk_id " hWnd
FileGetVersion, vPVersion, % vPPath
MAX_PATH := 260
;PROCESS_QUERY_INFORMATION := 0x400 ;PROCESS_VM_READ := 0x10
if !hProc := DllCall("kernel32\OpenProcess", UInt,0x410, Int,0, UInt,vPID, Ptr)
return
if !vAddress && A_Is64bitOS
{
DllCall("kernel32\IsWow64Process", Ptr,hProc, IntP,vIsWow64Process)
vPIs64 := !vIsWow64Process
}
です!!>>922 さんありがとうございました!
なんとアクティブタブのファイルパスアドレス見つかりました!
AHKですけど、よかったら皆さんこの関数使ってください!
;==================================================
JEE_GetAcroRd32Path(hWnd)
{
WinGetClass, vWinClass, % "ahk_id " hWnd
if !(vWinClass = "AcrobatSDIWindow")
return
WinGet, vPID, PID, % "ahk_id " hWnd
WinGet, vPPath, ProcessPath, % "ahk_id " hWnd
FileGetVersion, vPVersion, % vPPath
MAX_PATH := 260
;PROCESS_QUERY_INFORMATION := 0x400 ;PROCESS_VM_READ := 0x10
if !hProc := DllCall("kernel32\OpenProcess", UInt,0x410, Int,0, UInt,vPID, Ptr)
return
if !vAddress && A_Is64bitOS
{
DllCall("kernel32\IsWow64Process", Ptr,hProc, IntP,vIsWow64Process)
vPIs64 := !vIsWow64Process
}
933デフォルトの名無しさん
2020/11/28(土) 20:22:46.29ID:Sl4N7Gov AMD64やIA-32eのマニュアルに2バイトで0クリア出来るオペコードはないように見えるな
934デフォルトの名無しさん
2020/11/28(土) 20:23:26.87ID:kjtXSxRe if !vAddress
{
VarSetCapacity(MEMORY_BASIC_INFORMATION, A_PtrSize=8?48:28, 0)
vAddress := 0
Loop
{
if !DllCall("kernel32\VirtualQueryEx", Ptr,hProc, Ptr,vAddress, Ptr,&MEMORY_BASIC_INFORMATION, UPtr,A_PtrSize=8?48:28, UPtr)
break
vMbiBaseAddress := NumGet(MEMORY_BASIC_INFORMATION, 0, "Ptr")
vMbiRegionSize := NumGet(MEMORY_BASIC_INFORMATION, A_PtrSize=8?24:12, "UPtr")
vMbiState := NumGet(MEMORY_BASIC_INFORMATION, A_PtrSize=8?32:16, "UInt")
;vMbiProtect := NumGet(MEMORY_BASIC_INFORMATION, A_PtrSize=8?36:20, "UInt")
vMbiType := NumGet(MEMORY_BASIC_INFORMATION, A_PtrSize=8?40:24, "UInt")
vName := ""
if (vMbiState & 0x1000) ;MEM_COMMIT := 0x1000
&& (vMbiType & 0x1000000) ;MEM_IMAGE := 0x1000000
;&& (vMbiProtect = 0x4) ;PAGE_READWRITE := 0x4
{
vPath := ""
VarSetCapacity(vPath, MAX_PATH*2)
DllCall("psapi\GetMappedFileName", Ptr,hProc, Ptr,vMbiBaseAddress, Str,vPath, UInt,MAX_PATH*2, UInt)
if !(vPath = "")
SplitPath, vPath, vName
}
{
VarSetCapacity(MEMORY_BASIC_INFORMATION, A_PtrSize=8?48:28, 0)
vAddress := 0
Loop
{
if !DllCall("kernel32\VirtualQueryEx", Ptr,hProc, Ptr,vAddress, Ptr,&MEMORY_BASIC_INFORMATION, UPtr,A_PtrSize=8?48:28, UPtr)
break
vMbiBaseAddress := NumGet(MEMORY_BASIC_INFORMATION, 0, "Ptr")
vMbiRegionSize := NumGet(MEMORY_BASIC_INFORMATION, A_PtrSize=8?24:12, "UPtr")
vMbiState := NumGet(MEMORY_BASIC_INFORMATION, A_PtrSize=8?32:16, "UInt")
;vMbiProtect := NumGet(MEMORY_BASIC_INFORMATION, A_PtrSize=8?36:20, "UInt")
vMbiType := NumGet(MEMORY_BASIC_INFORMATION, A_PtrSize=8?40:24, "UInt")
vName := ""
if (vMbiState & 0x1000) ;MEM_COMMIT := 0x1000
&& (vMbiType & 0x1000000) ;MEM_IMAGE := 0x1000000
;&& (vMbiProtect = 0x4) ;PAGE_READWRITE := 0x4
{
vPath := ""
VarSetCapacity(vPath, MAX_PATH*2)
DllCall("psapi\GetMappedFileName", Ptr,hProc, Ptr,vMbiBaseAddress, Str,vPath, UInt,MAX_PATH*2, UInt)
if !(vPath = "")
SplitPath, vPath, vName
}
935デフォルトの名無しさん
2020/11/28(土) 20:25:32.47ID:kjtXSxRe if InStr(vName, "AcroRd32.dll")
{
;get address where path starts
;if vPIs64{
; vAddress := vMbiBaseAddress + 0x19d3d9c
;}
;else{
vAddress := vMbiBaseAddress + 0x19d3d9c
;}
break
}
vAddress += vMbiRegionSize
if 0
if (vAddress > 2**32-1) ;4 gigabytes
{
DllCall("kernel32\CloseHandle", Ptr,hProc)
return
}
}
}
{
;get address where path starts
;if vPIs64{
; vAddress := vMbiBaseAddress + 0x19d3d9c
;}
;else{
vAddress := vMbiBaseAddress + 0x19d3d9c
;}
break
}
vAddress += vMbiRegionSize
if 0
if (vAddress > 2**32-1) ;4 gigabytes
{
DllCall("kernel32\CloseHandle", Ptr,hProc)
return
}
}
}
936デフォルトの名無しさん
2020/11/28(土) 20:26:33.51ID:kjtXSxRe VarSetCapacity(MEMORY_BASIC_INFORMATION, A_PtrSize=8?48:28, 0)
if vAddress
&& DllCall("kernel32\VirtualQueryEx", Ptr,hProc, Ptr,vMbiBaseAddress, Ptr,&MEMORY_BASIC_INFORMATION, UPtr,A_PtrSize=8?48:28, UPtr)
{
memVal := ReadMemory32(vAddress, 0, vPID)
memVal := ReadMemory32(memVal, 0x78, vPID)
memVal := ReadMemory32(memVal, 0x18, vPID)
memVal := ReadMemory32(memVal, 0x10, vPID)
memVal := ReadMemory32(memVal, 0x10, vPID)
;memVal += 0x0
vPath := ""
VarSetCapacity(vPath, MAX_PATH*2)
DllCall("psapi\GetMappedFileName", Ptr,hProc, Ptr,vMbiBaseAddress, Str,vPath, UInt,MAX_PATH*2, UInt)
if InStr(vPath, "AcroRd32.dll")
{
vPath2 := ""
VarSetCapacity(vPath2, MAX_PATH*2, 0)
DllCall("ReadProcessMemory", "UInt", hProc, UInt, memVal, Str, vPath2, Uint, MAX_PATH*2, UPtr,0)
vPath3 := StrGet(&vPath2, "cp932")
}
}
DllCall("kernel32\CloseHandle", Ptr, hProc)
return vPath3
}
if vAddress
&& DllCall("kernel32\VirtualQueryEx", Ptr,hProc, Ptr,vMbiBaseAddress, Ptr,&MEMORY_BASIC_INFORMATION, UPtr,A_PtrSize=8?48:28, UPtr)
{
memVal := ReadMemory32(vAddress, 0, vPID)
memVal := ReadMemory32(memVal, 0x78, vPID)
memVal := ReadMemory32(memVal, 0x18, vPID)
memVal := ReadMemory32(memVal, 0x10, vPID)
memVal := ReadMemory32(memVal, 0x10, vPID)
;memVal += 0x0
vPath := ""
VarSetCapacity(vPath, MAX_PATH*2)
DllCall("psapi\GetMappedFileName", Ptr,hProc, Ptr,vMbiBaseAddress, Str,vPath, UInt,MAX_PATH*2, UInt)
if InStr(vPath, "AcroRd32.dll")
{
vPath2 := ""
VarSetCapacity(vPath2, MAX_PATH*2, 0)
DllCall("ReadProcessMemory", "UInt", hProc, UInt, memVal, Str, vPath2, Uint, MAX_PATH*2, UPtr,0)
vPath3 := StrGet(&vPath2, "cp932")
}
}
DllCall("kernel32\CloseHandle", Ptr, hProc)
return vPath3
}
レス数が900を超えています。1000を超えると表示できなくなるよ。
ニュース
- 「おこめ券は米以外の食品も買える。効果的な活用を」 地元で農水相 [山形県] [少考さん★]
- 【速報】「女芸人No.1決定戦 THE W」9代目女王にニッチェ! 7年ぶり3度目で悲願の優勝 [牛丼★]
- 【芸能】『女芸人No.1決定戦THE W』 粗品が最後にバッサリ「優勝賞金1000万円にしてはレベル低い大会」 [冬月記者★]
- 今年の流行語大賞 『働いて働いて働いてまいります』が受賞で不快感… 過労自殺の遺族らが会見「家族にむち打つような行為だ」 [冬月記者★]
- 【東京】「家族で話題にして」 “世田谷一家殺害から25年 警視庁が呼びかけ [煮卵★]
- 【広島】ペルー女性の国保加入を誤って認め、福山市が医療費484万円を肩代わりするミス…入院して手術を受ける [ぐれ★]
