いてつくブログ

2ちゃんねるのスレッドをコピペしてまとめてみるブログ

xmm

PC等【C++】高速化手法【SSE】

1 :デフォルトの名無しさん:2005/10/27(木) 02:55:36
C++やインラインアセンブラ、SSEなどによる高速化の手法
について語りましょう。

178 :デフォルトの名無しさん:2009/01/07(水) 23:00:55
メモリ(バキューン!)とかを考慮すると構造体より配列のほうが高速?

179 :デフォルトの名無しさん:2009/01/08(木) 00:02:43
>>178
同じ。

185 :デフォルトの名無しさん:2009/01/09(金) 14:29:17
>>179
うほ?
>>178の意味がいまいち分からんが、
char array[0x100];

struct{char value;} array[0x100];
だったらレジスタサイズにパディングされる分、構造体の方が早くね?
ちなみに、同じ事だが容量気にして構造体のなかでshortとか使うと
パデイング入るんでメモリに無駄が発生する。
まぁ、パディングを知っていれば無駄を防ぐこともできるけど。

189 :デフォルトの名無しさん:2009/01/11(日) 01:50:19
>>185
> struct{char value;} array[0x100];
> だったらレジスタサイズにパディングされる分、構造体の方が早くね?

pragmaやattributeでパックしない限りpaddingは入らないだろ。

191 :,,・´∀`・,,)っ-●◎○:2009/01/11(日) 06:05:36
>>189
構造体やその配列の場合、パディングが入る。
デフォルトが4バイト単位だったかな?

360 :デフォルトの名無しさん:2009/09/08(火) 20:07:19
だんごじゃないけどi5はi5だよ。それ以上でもそれ以下でもない。

361 :デフォルトの名無しさん:2009/09/08(火) 20:13:34
>>360
おめーみたいなカスには聞いとらん失せろゴミが
ダンゴさんマダー?

363 :デフォルトの名無しさん:2009/09/08(火) 21:25:40
>>361
ちょwだれww
ほれ、なんかcore2の時とかこれはいいぜーとかなんか詳しく言ってたような気がしたから
i7なりi5なりのアーキテクチャ面からの意見を聞いてみたかったんだ

382 :デフォルトの名無しさん:2009/09/10(木) 00:35:11
おい!テーブル使わん言ったじゃねえかよ。氏ねカス。

387 :デフォルトの名無しさん:2009/10/08(木) 03:33:43
unsigned int mod6(unsigned int m){
unsigned int a = 0;
static unsigned int x[] = {0,2,4,0,2,4,0,2,4,0,2,4,0,2,4,0,2,4,0,2,4,0,2,4};
__asm{
mov eax, m
test eax, 1
jz Mod3
inc a
Mod3:
shr eax, 1
lea ebx, x
mov edx, eax
and eax, 0000ffffh
shr edx, 16
add eax, edx
mov edx, eax
and eax, 0000003fh
mov ecx, edx
and edx, 00000fffh
shr ecx, 12
shr edx, 6
add eax, ecx
add eax, edx
mov edx, eax
and eax, 0000000fh
shr edx, 4
add eax, edx
mov edx, x[eax*4]
add a, edx
}
return a;
}

399 :デフォルトの名無しさん:2009/10/08(木) 15:58:42
逆数乗算で商を求めて元の値から引いたほうが速い
今のCore MAでは整数乗算は浮動小数除算機と兼用してて
非除数 - (除数×小数点以下切り捨てた商)

まあベンチ取ってみればわかるがコンパイラの吐くコードにも勝てんと思う

401 :デフォルトの名無しさん:2009/10/08(木) 17:45:39
static??const??int??rcp6??=??1.0??/??6.0??*??std::pow(2.0,16.0);
int??x??=??255??-??((255??*??rcp6)??>>??16)??*??6;

確かにこれで十分な気がするし、>>387より速そうだ。


414 :デフォルトの名無しさん:2009/10/09(金) 01:24:41
>>387
inline unsigned int mod6(unsigned int a){
 unsinged int b = (a >> 3) + (a >> 5); // /6
 unsinged int c = (b << 1) + (b << 2); // *6
 return a - c;
}

456 :デフォルトの名無しさん:2009/10/22(木) 03:07:47
C/C++でメモリプール(int, doubleなど様々な型が共存)を作り、
メモリプール内部でメモリの詰め直しを行って最適化しようと試みています。

入門書+α(boostがわかるぐらい)なので、
キャッシュやメモリに関する特殊なことは全然わかりません。
何か気をつけなければならないことや忠告があれば教えてください。

488 :,,・´∀`・,,)っ-○○○:2009/10/28(水) 04:46:10
for (i = 0; i < N; i+=4) {
  sum1 += A[i];
  sum2 += A[i+1];
  sum3 += A[i+2];
  sum4 += A[i+3];
}
sum = sum1 + sum2 + sum3 + sum4;

っていうか組み込み関数使えよ

498 :デフォルトの名無しさん:2009/10/29(木) 08:44:26
>>488
これってNがわかっていないとコンパイラはやってくれないよね?
ICCだと出来るのかな?
GCCではベクトル化してくれなかった。

539 :デフォルトの名無しさん:2011/01/28(金) 11:43:56
x86は浮動小数点が弱くて仕方がないからなあ
8087のコプロセッサの頃からの負の遺産を引きずっている
でもL1/大容量L2キャッシュを媒介にする事によって相当克服して来てはいるんだけどな
PowerPCなどにどうしても勝てない

596 :デフォルトの名無しさん:2011/05/30(月) 10:20:14.97
結論から言うとメモリの転送がボトルネックです。
書き出しのアライメントを揃える事とstreamを使う事で何割かは改善出来ますが、基本的に速く出来ません。

最適化とは遅い部分を探し出す事に他なりません。
安直にSSEとかマルチプロセッサにしようと思わず、真にボトルネックを見つけられるようになりましょう。

真に遅い部分が分かったなら、平均化フィルタと何が違うのか、どうしてもう速く出来ないのかが理解出来るようになります。

598 :デフォルトの名無しさん:2011/06/13(月) 15:11:06.75
>>596
メモリの転送がボトルネックなのか、演算部分がボトルネックなのかは
どうやって判断すればいいのですか?つまりどこを見たらよいのか。
あるいはあなたはどうやってますか?
ツールとか使うのでしょうか?

618 :デフォルトの名無しさん:2011/07/02(土) 22:44:49.03
mapの方がアライメントされてないんじゃない?

619 :デフォルトの名無しさん:2011/07/02(土) 23:38:54.68
std::pair<int, hoge>からaligned_stl::pair<int, hoge>へのコードがバグってるんじゃないの

620 :618:2011/07/03(日) 00:21:26.44
適当な事書いたと思ったけど、std::mapにカスタムアロケータでいけるっぽい
http://ideone.com/sOWl6



621 :デフォルトの名無しさん:2011/07/03(日) 02:45:36.94
>>618
mapの方は、__declspec(align(16))みたいなことはしてませんが
カスタムアロケータを渡しており、カスタムのpair(aligned_stl::pair)を使うように指定してます。

>>619
わかりづらくてすみませんorz
std::pairは一切使っておらず、aligned_stl::pairのみです。
make_pairもaligned_stl::pairを返します。

>>620
ありがとうございます、Win7 64bitのVC2008Expressで動かしてみましたが
カスタムアロケータのc.insertで、Hoge()の引数なしのコンストラクタで落ちます(x_ = static_x)
Hoge hoge;
c.insert( ::std::make_pair<int,Hoge>(i, hoge) );
とやると、make_pairのところのコピーコンストラクタで落ちます( x_ = src.x_)。
なので、前回書いたのと同様に
Hoge hoge;
std::pair<int, Hoge> pairArg(i, hoge);
とやってからpairArgを渡すと落ちませんでした(c.insertのみ。d.insertは落ちる)。

どうもpairに関してはアラインメント指定しなくても、中のメンバが
アラインメント指定されていれば問題ないようですね(アロケータだけでよい?)。
もうちょっと試してまた報告します。
ただ、2008だとアラインメント指定が一時オブジェクトに対して効かないと考えたほうが
いいのかもしれませんね(´・ω:;.:...  (インライン展開された場合は除く)
ありがとうございました。

638 :デフォルトの名無しさん:2011/07/05(火) 22:56:13.54
余分なカッコが多すぎるコードってみにくくて嫌いだ。

if (a == 0 && b == 0 || c == 0 && d == 0)

if ((((a == 0) && (b == 0)) || ((c == 0) && (d == 0))))

この二つだと上の方がはるかに見やすいと個人的には思うが、
見やすさを優先してカッコをつけるとか言って下のように書く人がいる。


649 :デフォルトの名無しさん:2011/10/10(月) 19:26:30.72
指定桁数で四捨五入する以下の関数の実行速度を上げたいの。
(valueは0~9999、digitsは0~5が保証される)
SSE使って高速化頼む。

double NormalizeDouble(double value, int digits) {
  static double t0[] = { 1, 10, 100, 1000, 10000, 100000 };
  static double t1[] = { 1, 0.1, 0.01, 0.001, 0.0001, 0.00001 };
  return (int)(value * t0[digits] + 0.5) * t1[digits];
}

652 :デフォルトの名無しさん:2011/10/10(月) 19:49:57.12
>>649
最適化スレで終了宣言してからにしろよ

653 :デフォルトの名無しさん:2011/10/10(月) 19:50:50.26
でもベクトル化で少しは早くなるわよ

664 :デフォルトの名無しさん:2011/12/17(土) 22:41:12.80
signed shortの配列に
floatもしくはdouble型の乗算をして
クリップ処理をほどこし
signed shortの配列に戻すのを
SSEにしたいのでやってください


これ

signed short s[100];
float f
init a;

for (a=0;a<100;a++)
s = s[a] * f;

665 :デフォルトの名無しさん:2011/12/17(土) 23:06:34.33
それ、どう考えても実数型⇔整数型のコストがでかすぎる。
たった100件でいいなら実数で持てないの?

679 :デフォルトの名無しさん:2011/12/19(月) 02:15:44.43
初めてSSEに触れるので、まずは簡単なコードを作成してみたのですが、
SSEを使わないほうが40倍も速いという驚愕の結果が出ました。
何が間違っているんでしょうか??

コンパイラ:VC++2005(Releaseモード、浮動小数点モデル:FAST)

float* f4pakAdd( float* pfA, float* pfB )
{
  _declspec( align( 16 ) ) static float fC[ 4 ];
  
  _asm
  {
    mov ebx, pfA
    movaps xmm0, oword ptr [ebx]
    mov ebx, pfB
    movaps xmm1, oword ptr [ebx]
    addps xmm0, xmm1
    movaps fC, xmm0
  }
  
  return fC;
}

呼び出し側

for( int i = 0; i < 10000000; i++ )
{
  pfC = f4pakAdd( fA, fB );
}

682 :デフォルトの名無しさん:2011/12/19(月) 02:34:54.14
パイプライン化したコードでもないし、スタックチェックが行われている気がするが。
逆アセ確認したかい?

707 :デフォルトの名無しさん:2011/12/23(金) 11:26:47.88
どんな変数も問答無用でアライメント16にするようにコンパイルする設定があれば
面倒な記述を減らせると思うんですが、何かデメリットあるんでしょうか?
メモリの隙間ができて勿体無いとかあるかもしれませんが、メモリ量の多い昨今、
それほど問題にならないのでは?と思います。
むしろアライメントすることでメモリアクセスの冗長さを減らせて帯域を節約する効果も
あって一石二鳥ではと思うんです。

708 :デフォルトの名無しさん:2011/12/23(金) 11:59:03.43
gccだと-mpreferred-stack-boundary=4がデフォルトだから既に16バイトアライメントだよ
構造体の詰め物は互換性もあるし難しいじゃないか

710 :,, ・´ ∀ `・ ,,)っ-○○○:2011/12/23(金) 12:41:37.02
>>707
なにそれ君いまだにPS3向けのゲームとか組まされてるわけ?

711 :デフォルトの名無しさん:2011/12/23(金) 15:57:24.48
>>708
glibcのmallocは8バイトだよ

>>710
SandyBridgeでもアラインメント取れてないと遅いでしょ

713 :デフォルトの名無しさん:2011/12/23(金) 17:19:17.60
>>711
Nehalem以降はmovups/dquもペナルティ無く使えるでしょ
まあ結局Core2以前も考慮するとコード振り分けるから労力は変わらないのだけれど...

714 :707:2011/12/24(土) 02:12:26.59
すみません、自分は日曜プログラマレベルで、対象CPUはx86、環境はVC++です。
VC++の設定を見ていると、「構造体メンバのアライメント」というのがあって16バイトアライメントを選べるようになってました。
同様に通常の変数もアライメントできる設定があるかと思い探しましたが見付かりませんでした。

715 :デフォルトの名無しさん:2011/12/24(土) 02:18:17.32
どう考えてもこれ以上削れないってくらいの手書きインラインアセンブリコードに対し、
C記述版をVC++のReleaseモード(最適化O2)でコンパイルしたもののほうが1.3倍速かったです。
生成されたアセンブリを覗いてみたところ、

変数 * 3

というコードを

lea edx, DWORD PTR [eax+eax*2]

としていてびっくりしました。
これって、アドレス演算を行うローダ(専用の演算器?)を使うことで、
通常のALUと並行して演算(スーパースカラって言うんでしたっけ?)し
高速化しているということなんでしょうか??

716 :デフォルトの名無しさん:2011/12/24(土) 02:34:46.72
>>714
__declspec(align(N))

717 :707:2011/12/24(土) 02:44:05.59
>>716
ありがとうございます。
それは知っているんですが、>>707でも書いた通り、
そういった記述をわざわざせずとも、自動で全てアライメントしてくれるような設定があればイイのでは?
と思った次第です。

しかし、上でも仰られたように、互換性の問題があったりで難しいのでしょうね・・・
でも二重インクルード防止の「#pragma once」のように、互換性を考慮しない機能があったりするくらいですから、
自分のようにずっとVC++しか使わない人間を対象にそういうオプションが用意されていても良いのではと思いました。

733 :デフォルトの名無しさん:2012/03/09(金) 12:53:25.77
unsigned int maxpos(unsigned int src[256])
{
unsigned int i, m = 0;
for(i = 1; i < 256; i++)if(src[m] < src[i])m = i;
return m;
}
これをSSEで高速化する方法があれば教えて下さい

739 :デフォルトの名無しさん:2012/03/11(日) 00:41:15.69
>>733
画像とか統計の基礎だな。疑似コードで書くとこんな感じだ

maxpos(src[256]) {
pos = {0, 1, 2, 3};
for(i=0; i<256; i+=4) {
 s=load(&src[i]);
 isGT=maxVal<s;
 maxVal=isGT&s | ~isGT&maxVal;
 maxPos=isGT&pos | ~isGT&maxPos;
 pos += 4;
}
return max_position(
 maxVal[0], maxPos[0],
 maxVal[1], maxPos[1],
 maxVal[2], maxPos[2],
 maxVal[3], maxPos[3]);
}

762 :,, ・´ ∀ `・ ,,)っ-○○○:2012/03/14(水) 07:23:58.09
packed unsigned intの比較(マスク生成)だけど、両項のMSBを反転してからpcmpgtdするより
psubd + psradのほうが速いかもしれない

768 :デフォルトの名無しさん:2012/03/21(水) 23:53:20.16
P6,P2,P3,P4はforwardならnot taken backwardならtakenがデフォルト
P4はPrefixでヒントを出せる
PM,Core2はランダム
ソースはAgner

775 :デフォルトの名無しさん:2012/03/24(土) 21:41:50.71
そう思ってくれるのはいいが、間違いの指摘と
実際はどうなってんのか答えてくれ
批難だけの回答はいらん。

778 :デフォルトの名無しさん:2012/03/24(土) 21:52:06.49
>>775
じゃあ間違いを指摘してやる。

>大概returnやthrowが行われるからifをすっ飛ばせば速いのは解る。
前方への条件分岐は、「分岐しない」と予測される、とオマエ以外の全員が言っている。
if (xx) return
で「すっ飛ばせば云々」なんて、理解していないまま「わかったつもりになってるだけ」の証拠。

>今のCPUは分岐ヒントとか投棄とかあって単純じゃないんだろ
ヒントはともかく、投機はまさに「投機実行するために分岐予測をする」のであって
「投機実行もあるから分岐予測が複雑になる」はナンセンス。
もちろん、エンプラ系/VLIW系では「分岐の有無の両経路を実行する」なんてのもある(らしい)が
一般的とは言いがたい。

779 :デフォルトの名無しさん:2012/03/24(土) 21:59:34.64
>>778
内容じゃなく国語的に誤解されてるな。

>前方への条件分岐は、「分岐しない」と予測される、とオマエ以外の全員が言っている。
if( xx ) throw xxx;
throwなんて実行するケース殆ど無いんだから基本if実行しないってのは同じ話。
矛盾してないでしょ。

まず分岐予測が複雑になってるって話はしてないよ。
投棄実行については投棄実行を考慮した上での静的予測方法があるでしょという話。

780 :デフォルトの名無しさん:2012/03/24(土) 22:04:11.41
>>779
だから、ifの内部は「実行すると予測される」んだよ、バーカ

782 :デフォルトの名無しさん:2012/03/24(土) 22:06:41.25
せめて正しい漢字使えよ。

一度なら単なる変換ミスとして納得できるけど
繰り返しているってことは、別の意味に捉えているとしか思えない。

783 :デフォルトの名無しさん:2012/03/24(土) 22:09:32.88
>>780
お前バカだろ
みんなアセンブリ前提で言ってんだよ

jze label   if() {
・・・処理・・・
labeli     }


789 :デフォルトの名無しさん:2012/03/24(土) 22:48:33.55
投棄実行については誤解してたわ。
2つの分岐を両方実行して実際実行対象にならなかった方の結果を破棄するものだと思ってた。

792 :デフォルトの名無しさん:2012/03/24(土) 23:01:04.27
一応。

突然returnやthrowが出てくるのが
if (xx) return
という意味じゃないか、というのも勝手に俺が頭の中で補って想像しただけで
実際には何の説明も無く(ifの多くがreturnやthrowというのにも同意しにくい)
唐突な「rerturnやthrow」「すっ飛ばす」を必死に理解しようとしたのがそもそもの間違いかもね。

794 :デフォルトの名無しさん:2012/03/24(土) 23:04:39.09
>>792
>>779で補足だしてるだろしつこいわ

803 :デフォルトの名無しさん:2012/03/25(日) 16:12:43.94
インテルの最適化マニュアルだと
>インテルPentiumM??プロセッサー、インテルCoreSolo??プロセッサー、インテルCoreDuoプロセッサーは、
>ジャンプの向きに従った条件分岐を静的には予測しない。これらのプロセッサーでは、
>すべての条件分岐は、最初に発生したときでも動的に予測される。
と書いてあって、wikiで調べたらPenM以降は広域分岐予測を取り入れた関係で静的予測はしなくなったみたいだね
http://ja.wikipedia.org/wiki/%E5%88%86%E5%B2%90%E4%BA%88%E6%B8%AC

>>768
>PM,Core2はランダム
というよりも、「前に実行した別の分岐命令の結果も影響する」とした方が適切みたいだ

分岐予測に関して
http://news.mynavi.jp/column/architecture/index.html
の第167回からの解説が参考になるよ



http://toro.2ch.net/test/read.cgi/tech/1130349336/l50/../人気ブログランキングへ

PC等機械語なら俺に質問しろ!

1 :デフォルトの名無しさん:02/10/22 21:04
漏れは今までにC、C++、Pascal、HSP、JS、VBなど
数々の言語を極めてきたがやはり一番手にしっくりくる言語は機械語だ。

だから、機械語のことなら何でも質問しろ!
ただプログラムのコードなんかは長くなるがな。

92 :かじゅ猫:03/03/04 00:20
アセンブラなら書けるけど
やっぱり機械語書けたほうが良いのかな?
良い参考書あったら教えてくださいな

93 :デフォルトの名無しさん:03/03/04 00:28
>>92
それは公式のドキュメントをみるしかないような。
書けるひつようはないと思うけど、binutilsやデバッガに
手を入れるには必須だよね。

99 :デフォルトの名無しさん:03/03/04 17:39
機械語でできる仕事って何がありますか?

100 :名無しさん@Emacs:03/03/04 17:48
>>99
機械語は多くの場合組むものじゃない。
それを生成するプログラムを組む、これが人間のやること。

118 :デフォルトの名無しさん:03/04/02 14:50
http://www.falcom.co.jp/ys/support/yse_easy.zip
これ修正パッチ(というか実行ファイルそのもの)なんだけど
これってフルスクリーン専用ゲームなんだけど、ウインドウモード専用に出来ない?

バイナリエディタで開いても俺にはさぱりわからない・・・


156 :1だよん:03/06/02 18:36
マトリックスに0と1だけでプログラミングできる奴いなかったけ?

164 :デフォルトの名無しさん:03/06/05 23:11
本気で質問です。

コマンドプロンプトを使うと、
C:¥>
と出ずに、
C:¥>Documents and Settings¥○○>
と出てしまいます。
どうすれば、
C:¥>
と出せるのでしょうか?

ここで、つまづいています…
使っているOSはウィンドウズXPです。

165 :デフォルトの名無しさん:03/06/06 01:32
>>164
C:\Documents and Settings\○○>
が長いのが気に入らないのかな?

PROMPT=$N:\$G
ってすれば
C:\>
って出るよ。

ユーザー環境変数に追加しておけば、
毎回指定しなくてもいい。
 システムのプロパティ→詳細設定→環境変数→ユーザー環境変数→新規→
 変数名:PROMPT 変数値:$N:\$G

なぜ機械語スレに書くのか分からんが。

173 :デフォルトの名無しさん:03/06/21 23:40
386の命令は可変長。命令の構造は以下の通り。この辺りは誰でも知ってるか。
前置バイト + オペコード + MODRM + アドレスディスプレースメント + 即値定数

386のこの命令の表現形式を頭に叩き込んでるところ。掛け算の九九並に体に馴染ませてから
NTLDRを読み始めたいと思います。

177 :名無し@沢村:03/06/22 06:38
>>173
違うよ。
オペコード(1または2バイト)+MODRM(1バイト)+SIB(1バイト)+アドレスディスプレースメント(1または2または4バイト)+即値定数(1または2または4バイト)
だよ。
またMODRMはmod(7-6ビット)、reg(5-3ビット)、R/M(2-0ビット)の各フィールドからなるんだよ。
例えば、MOV(reg1からreg2へ)命令の場合、
100100w 11reg1reg2なんだよ。
wというのは、16ビットか32ビットかを指定するもので、それによってレジスタが決まるんだよ。
命令によってはオペコードの中にwフィールドがないものもあり、その場合はregフィールドの値だけでレジスタが決まるんだよ。
まあ、他にもややこしいことはいろいろあるよ…



201 :デフォルトの名無しさん:03/08/06 18:10
int mc91(int n){
if (n>100) return n-10;
else return mc91(mc91(n+1));
}

上のCプログラムを出来ればアセンブリでおながいします m(_ _)m

207 : :03/12/15 01:05
浮動小数点のフォーマット(データ構造)と、四則演算のやり方を説明できる方いませんか?
あるいは、こういうこと解説してある本でも良いんですけど。

今はとりあえず我流で3バイトの整数部+1バイトの指数部(X*2^n)でやってるんですが、
なんか違うというか、もっと上手いやり方があるような気がして。

210 :デフォルトの名無しさん:03/12/15 02:11
>>207
フォーマットは、IEEEの規格があるのでCPUのマニュアルなんかに書いてあるはず。
足し算引き算は、指数部の桁を合わせて仮数部を計算。
掛算は、指数部を足し算して仮数部だけで掛算。
割算は、指数部を引き算して仮数部だけで割算。

誤差がどうのこうのってな事があるので、数値演算の本を読んだほうがいいと思う。


211 :デフォルトの名無しさん:03/12/15 09:29
>>207
ftp://download.intel.co.jp/jp/developer/jpdoc/24547003_j.pdf
第8章を参照。

213 :207:03/12/15 22:58
>>210,>>211
レスありがとうございます。

>>211
あ、私の説明が全く不十分だったのですが、8ビットの加減算しか出来ないCPUで
(今使っているのは8051って石の派生チップなんですが)Cのfloat相当の
浮動小数点の処理を効率よくやる方法はないものかな、と思っておりまして。

でもレスありがとうございます。

359 :何か教えてくれ:04/12/13 21:32:43
1F 8B 08 08 20 7B BD 41 02 0B 65 7A 72 6D 69 64
32 2E 64 6C 6C 00 F3 8D 9A C0 C0 CC C0 C0 C0 02
C4 FF FF 33 30 EC 60 80 00 07 06 C2 60 03 10 F3
C9 EF E2 63 D8 C2 79 56 71 07 A3 CF 59 C5 90 8C
CC 62 85 82 A2 FC F4 A2 C4 5C 85 E4 C4 BC BC FC
12 85 A4 54 85 A2 D2 3C 85 CC 3C 05 17 FF 60 85
DC FC 94 54 3D 5E 5E 2E 15 A8 19 EE D7 BF DF 66
DE 36 B3 03 86 FF 4F EB EE 60 02 D2 DF 56 76 81
E9 A0 CC E4 0C 90 38 CC CE 00 57 06 06 1F 46 66
06 F9 EA BD 8E 30 B1 07 0C 7C 8A DC 8C AC 3C 0C
4C 50 8F 80 80 00 14 2B 40 79 20 36 13 42 1A 46
83 3D 0A E5 30 C1 34 0A 20 D3 50 0A 68 4E 00 11
61 C2 60 C0 C0 C0 C3 40 7D A0 57 92 5A 51 02 A4
DD 60 0E 42 F6 2B 14 00 9D 98 A0 57 94 92 58 92
08 75 AB 02 54 1D 1B AA 3A A0 97 1D F4 8A 52 73
F2 93 A1 6E 35 80 AA E3 C0 50 E7 C4 30 0A 86 35
D8 C1 08 24 0E F1 30 84 85 07 EE 53 03 E6 92 EE
1A 15 91 9D A0 74 F0 79 29 58 2A 32 3E EE 10 07
83 F6 9D 8F 8D 0C 13 22 E7 9A 98 4B EB C5 07 EB
88 29 3A EE C9 3F 20 10 C1 DB A0 20 FF 3F D5 D2
EC CB 68 38 0E 65 00 2B 4B 8D 80 E5 05 28 CE 61
58 03 C8 D7 01 62 03 20 E6 00 96 39 76 E0 B2 34
B5 AA 28 37 33 C5 48 2F 25 27 87 C1 39 31 27 C7
AD 34 2F B9 24 33 3F 2F B8 24 B1 A8 64 34 30 87
1A 10 80 D4 01 3C 06 A3 41 31 12 01 00 BB 4E 94
BB 00 0A 00 00

393 :デフォルトの名無しさん:05/02/15 22:09:44
>>359
おっ、なかなか面白いプログラムだね。
まあ、実用性重視して、4行目の一つ目、C9
としたのは、まあ許せるけど、次の EF は、×。

正解は、EAだ。 そうしないと無限ループに
おちいる。 とにかく、楽しいコーディングだな。
この機械言語見てるだけで、半日はイケる。


476 :デフォルトの名無しさん:2005/03/28(月) 12:18:37
訂正:
403000に0x64と入ってたとして

478 :デフォルトの名無しさん:2005/03/28(月) 14:45:10
>>476言っていることが解りませんがこうですか?

0x64(10進数で100)
1,0,0の文字コードが0x31,0x30,0x30

あなたの言いたいことは
a=100
printf("%s",a);
(のような事)にあたる
アセンブラのコード希望

488 :デフォルトの名無しさん:2005/06/05(日) 03:58:07
ELF形式、COFF形式などと言うらしい、バイナリフォーマットの仕様を説明した
HPご存知でしょうか。
スクリプト言語でNASMクローンをつくれたら面白いかな、と思ったが、
どんなファイルを出力するのかでまずはまってしまて。。。

499 :デフォルトの名無しさん:2005/06/10(金) 04:15:06
今PEヘッダを勉強しているのですが、インポートデータの、ルックアップテーブルっていらなくないですか?


502 :499:2005/06/11(土) 05:28:31
すみません、馬鹿なのでよくわからないですが・・・
私にはアドレステーブルと全く同じデータのように思えるんですが、設計者は何らかの意図があってこういう形にしたわけなんでしょう?
設計意図を簡単でかまいませんので示唆して下さい。

505 :502:2005/06/12(日) 19:41:12
すみませんやっぱり馬鹿だった。USER32.DLLのインポートテーブルを見たらわかりました。

512 :505:2005/06/18(土) 11:41:59
わかったと思ったんだけどわからなくなりました・・・

OSのPEローダーは

1. (インポートする外部ルーチンの情報に関しては)ルックアップテーブルのみを参照してインポートを行う。アドレステーブルにどんなデータが入っていようと一切無視する。
2. ただし、ルックアップテーブルへのポインタが0だった場合には、アドレステーブルに入っているデータをルックアップテーブルの代わりに使う。

というようなアルゴリズムみたいですね・・・

2.の場合があるわけだから、やはりルックアップテーブルは必要がないのでは?

# それにしてもUSER32.DLLは不審だ・・・最初アドレステーブルにインポート済みらしいデータが入っているを見て、OSがインポートアドレスを厳密にチェックしているのか?と思ったんだけど、別に何もしていないみたい。(Win98の場合)

514 :デフォルトの名無しさん:2005/06/18(土) 20:54:07
よくは知らんが、再配置のアドレス解決は相当高くつくらしい。
OS自体全く違うがKDEはビルドのときにpreloadしておくと
起動時間が半分になるという話もある。

KERNEL32.DLLとかUSER32.DLLなどシステム固有のDLLは
どんなアプリでも同じアドレスにマップされる。(できる。)
しかしユーザ作成のDLLの場合、どんなアプリが何時ロード
するか分からんので、アドレス固定にすることは出来ない。

因みにVStudioはインストール時にアドレス解決するらしい。

>>512
という話と関係ある?

515 :デフォルトの名無しさん:2005/06/19(日) 00:08:32
499の言う「いらない」の意味がよくわからないんだが、
最終的にアドレステーブルだけあればいい=ルックアップテーブルを上書きすればいい、
つまり同じ用途で二箇所もいらないっていう意味で言ってるなら、そう言えないこともないかもな。
ローダーとモジュールの都合だけ考えれば。

ただ、両方テーブルがあると、デバッガとかでプロセス内部をのぞき見する場合には便利なことが多い。

たとえば、アドレス解決住みのアドレステーブルを見て何の関数なのか(可読名称)知りたいとき、
ルックアップテーブルが残ってれば名前テーブルがすぐ引ける。
ルックアップテーブルが残ってなければ、DLLのエクスポートテーブルを検索する必要がある。

また、API乗っ取り等のためにアドレステーブルを書き換えてしまった場合、
ルックアップテーブルが残ってれば、本来あるべきアドレスを再検索することができる。
ルックアップテーブルが残ってなければ、二度と本来のアドレスは分からない。
(まあ、本来のアドレスがわかったとして、それを素直に書き戻していいかは、
多重乗っ取りの可能性を考えると難しい面もないではないが、ここでは関係ない)

以上がPEの設計者が意図したものなのかどうかは知らないが、
そういう利用法はあるし、実際利用されてることを鑑みれば、
まるっきり無駄ってわけでもないとは言えると思う。


518 :512:2005/06/19(日) 22:44:11
>>515
>同じ用途で二箇所もいらない

そうそう!そういう意味です。

>両方テーブルがあると、デバッガとかでプロセス内部をのぞき見する場合には便利なことが多い。

そうなんですよ!だからこそ不審なんですよ。まるでクラッカーのために用意されているかのような2重テーブル。

OSの設計者が意図的にクラックしやすくするわけはないと思うので、何の意図があるのか、と思ったわけですが・・・

>>514
>KERNEL32.DLLとかUSER32.DLLなどシステム固有のDLLは どんなアプリでも同じアドレスにマップされる。

システムDLLでもOSのバージョンが違えば違うので、少なくとも普通のEXEとかユーザーDLLではビルド時解決は全くできないと思いますが・・・
USER32.DLLはたぶん特定のKERNEL32.DLL上でしか動かさないのでKERNEL32ターゲットのアドレステーブルが解決されていると思うんですが・・・
これって結局ロード時に上書きされちゃうんですよね・・・?
XPとかのUSER32.DLLはそうなってないですか・・・?

524 :デフォルトの名無しさん:2005/06/20(月) 04:45:51
>>518
>システムDLLでもOSのバージョンが違えば違うので、少なくとも普通のEXEとかユーザーDLLではビルド時解決は全くできないと思いますが・・・

書き方悪かったのかな。そういってるつもり。
だからVStudoはOSが特定できるインストール時なんでしょ。


528 :518:2005/06/25(土) 07:10:56
>>524
後で気がついたんだけど、514さんの書きこみは、'インポート'ではなく、'フィックスアップ'ですね。
「高価」というのは、DOS EXEからPEになって、絶対アドレスはすべてフィックスアップの対象になったわけで、場合によってはえらい数のリロケートが必要になる、ということでしょう。
フィックスアップは、通常ビルド時に仮想解決しますね・・・特にEXEは殆どの場合'望ましいベース'にロードできるので、リロケートが必要なく、素早いロード(安価)が可能となっているようです。

530 :528:2005/07/09(土) 05:31:17
やっとわかりました!
どうも、すみません。514さんので正しいみたいです。

http://www.windowsitlibrary.com/Content/356/11/4.html

この文書の
'BINDING IMPORTS FOR A PE FILE'
という項目に詳しく載っていました。

インポートデータの'アドレステーブル'が解決済みのファイルを'BOUND'、そのようなファイルを作ることを'BIND'と言うそうです。
'BOUND'のファイルはインポートデータの'タイムスタンプ'が0以外に設定されることで区別されます。
ローダーは、このタイムスタンプが、インポート対象モジュールのと同じかどうかチェックし、同じならアドレステーブルをそのまま使う、という仕組みみたいです。

そして、USER32.DLLはバウンドでした。

550 :デフォルトの名無しさん:2006/01/24(火) 16:01:10
4文字以下の文字列を入力して反転出力させなさい。
という問題できるかたいらっしゃいませんか?

558 :550:2006/01/24(火) 19:37:22
新たな問題です。
キーボードから文字列を入力し、その文字列に含まれる数字の数を、
コンソールへ表示するプログラムを作成せよ。
ただし、入力される最大文字列は、20文字とし 入力される文字は、
ASCIIコード表(プリント11ページ)に
載っている文字に限定する。
とのことです。だれか助けてください。。。。。。。

569 :デフォルトの名無しさん:2006/01/24(火) 21:08:19
マルチというか陥れたのは俺な訳だが。

570 :550:2006/01/24(火) 21:21:23
ありがとうございます。すいませんがLEAコマンドのいみが
よくわからなくてロードアドレスでなにをしてるんでしょうか?
また7行目とかでGR1、1、GR1とでてきますがレジスタとレジスタの
間の1は何のいみがあるんですか?他にもオペランド中に文字が3つならんだり
あんまりわかりません。。。すいませんがよければおしえてもらえませんか?

571 :デフォルトの名無しさん:2006/01/24(火) 21:24:05
>>569
責任とって詩ね

626 :デフォルトの名無しさん:2006/06/06(火) 23:43:43
最近組み込みのコードどうやって作ってるんだか知らんけど、
某エレベータの誤動作が問題になっているよな。
あれって、原因として
(1)センサー系統
(2)ROM内のコード
みたいなことが考えられると思うけど、俺は(2)が原因だと思う
あのクラスのコードサイズ(バイト数)、大体どれぐらい?
開発経費、ってか組み込み屋の労働単価ってどれくらいかな?
わかる?興味本位だが(笑


http://hibari.2ch.net/test/read.cgi/tech/1035288252/l50人気ブログランキングへ

学ばないブログ
忍者AdMax
記事検索
最新コメント
QRコード
QRコード
  • ライブドアブログ