すべてのCのコーダーにこんにちは。ポータブル(LinuxとWindowsがほとんど)4bytesの抽出/比較
私のような同様の質問が最初に見つかったので、見つけられませんでした。
4バイトをポータブルな方法でフェッチ/比較するには(もちろんmemcpy/memcmpは必要ありません)?
私はCを学んだことはありません。そのことから、基本を知ることなくすべてのことが厄介な混乱になるという生きた証拠です。 とにかく、(すでに)単語を書くことは、「アルファベットで始める」と言う時間がありません。
ulHashPattern = *(unsigned long *)(pbPattern);
for (a=0; a < ASIZE; a++) bm_bc[a]=cbPattern;
for (j=0; j < cbPattern-1; j++) bm_bc[pbPattern[j]]=cbPattern-j-1;
i=0;
while (i <= cbTarget-cbPattern) {
if (*(unsigned long *)&pbTarget[i] == ulHashPattern) {
上記のフラグメントは、Windows 32ビットコンパイラで必要な機能を果たします。私の望みは、64ビットのWindowsとLinuxでも同様に動作する4vs4の比較です。 何回も2,4,8バイトの転送が必要です。上記の例では、pbTargetオフセットから明示的に4バイトが必要です。 実際の質問:の代わりにどのようなタイプを使用すればいいですか?符号なしロング?(私はUINT16、UINT32、UINT64に近いものと思われます)。 言い換えれば、2,4,8バイトを表現するために私が必要とする3つのタイプはどれも、環境から独立してです。
この基本的な質問は多くの問題を引き起こすと考えられますので、明確にする必要があります。
アドオン2012-JAN-16:
@Richard J. RossのIII
私はダブル混乱しています! Linuxが1または2を使用しているかどうかわからない、つまりLinuxで定義されている_STD_USINGであるとすれば、 はどのグループが可搬性であるかということです。uint8_t、...、uint64_tまたは_CSTD uint8_t、...、_ CSTD uint64_t?
1] MVSから抜粋10.0 stdint.h
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef _ULonglong uint64_t;
2] 10.0 stdint.h
マイクロソフトC 32ビットで#if defined(_STD_USING)
...
using _CSTD uint8_t; using _CSTD uint16_t;
using _CSTD uint32_t; using _CSTD uint64_t;
...
MVSから抜粋は問題がない。
; 3401 : if (*(_CSTD uint32_t *)&pbTarget[i] == *(_CSTD uint32_t *)(pbPattern))
01360 8b 04 19 mov eax, DWORD PTR [ecx+ebx]
01363 8b 7c 24 14 mov edi, DWORD PTR _pbPattern$GSCopy$[esp+1080]
01367 3b 07 cmp eax, DWORD PTR [edi]
01369 75 2c jne SHORT [email protected][email protected]
しかし、64ビットがターゲットコードの場合、それはどうなりますか:
D:\_KAZE_Simplicius_Simplicissimus_Septupleton_r2-_strstr_SHORT-SHOWDOWN_r7>cl /Ox /Tcstrstr_SHORT-SHOWDOWN.c /Fastrstr_SHORT-SHOWDOWN /w /FAcs
Microsoft (R) C/C++ Optimizing Compiler Version 15.00.30729.01 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
strstr_SHORT-SHOWDOWN.c
strstr_SHORT-SHOWDOWN.c(1925) : fatal error C1083: Cannot open include file: 'stdint.h': No such file or directory
D:\_KAZE_Simplicius_Simplicissimus_Septupleton_r2-_strstr_SHORT-SHOWDOWN_r7>
Linuxのstdint.hではどうしてですか?
私はあきらめて、それをコメントしませんでした://#include <stdint.h>
、そしてコンパイルはOK行きました:
; 3401 : if (!memcmp(&pbTarget[i], &ulHashPattern, 4))
01766 49 63 c4 movsxd rax, r12d
01769 42 39 2c 10 cmp DWORD PTR [rax+r10], ebp
0176d 75 38 jne SHORT [email protected][email protected]
; 3401 : if (*(unsigned long *)&pbTarget[i] == ulHashPattern)
01766 49 63 c4 movsxd rax, r12d
01769 42 39 2c 10 cmp DWORD PTR [rax+r10], ebp
0176d 75 38 jne SHORT [email protected][email protected]
をこの非常に 'unsigned long型*' トラブル私のgcc -m64は右、QWORDないDWORDを取得しますので、?
1]
; 3400 : if (!memcmp(&pbTarget[i], pbPattern, 4))
01360 8b 04 19 mov eax, DWORD PTR [ecx+ebx]
01363 8b 7c 24 14 mov edi, DWORD PTR _pbPattern$GSCopy$[esp+1080]
01367 3b 07 cmp eax, DWORD PTR [edi]
01369 75 2c jne SHORT [email protected][email protected]
2]
; 3400 : if (!memcmp(&pbTarget[i], &ulHashPattern, 4))
01350 8b 44 24 14 mov eax, DWORD PTR _ulHashPattern$[esp+1076]
01354 39 04 2a cmp DWORD PTR [edx+ebp], eax
01357 75 2e jne SHORT [email protected][email protected]
3]
; 3401 : if (*(uint32_t *)&pbTarget[i] == ulHashPattern)
01350 8b 44 24 14 mov eax, DWORD PTR _ulHashPattern$[esp+1076]
01354 39 04 2a cmp DWORD PTR [edx+ebp], eax
01357 75 2e jne SHORT [email protected][email protected]
: @Mysticial
ちょうどマイクロソフトCLの32ビットV16によって行わ三つの異なる翻訳を見せたかったです
Th最初の目標は、1つのmov命令(*(uint32_t *)&pbTarget [i])を抽出し、長さが4バイトのレジスタ変数、すなわち1つのRAMが単一命令内の1つの比較にアクセスすることを比較することであった。 Nastilyは、memcmp()の3回のRAMアクセス(4バイト以上を指すpbPatternに適用)を2に減らしただけで、インライン展開に感謝しました。 pbPatternの最初の4バイト(2のように)にmemcmp()を使用する場合、ulHashPatternは型レジスタではなく、3]はそのような制限を必要としません。
; 3400 : if (!memcmp(&pbTarget[i], &ulHashPattern, 4))
上記の行は、(ulHashPatternは以下のように定義される:unsigned long型ulHashPatternを登録;):エラーになります
strstr_SHORT-SHOWDOWN.c(3400) : error C2103: '&' on register variable
はい、あなたは右のとおりです。memcmp()状況は(これに限定して保存します) - フラグメント2]は、3]マイナスダーティスタイルと同じです。 明らかに、手動でコード化されたときに関数を使用しないという私の傾向は過去のものですが、私はそれが好きです。
まだコンパイラがうまくいきません。ulHashPatternをレジスタ変数として定義しましたが、RAMから毎回ロードされますか?たぶん私は何かが恋しいですが、これは非常に(mov eax、DWORD PTR _ulHashPattern $ [esp + 1076])の行がパフォーマンスを低下させます。私の見解では醜いコードです。
stdint.hで定義されているuint64_tとその対応部分を確認してください。 –
Richard Ross IIIさん、私は(私が家に帰ると)相手を探します。おそらく彼らはstdint.hにいるので、 ? – Georgi