・rdtsc
=Aが64bitではrdx:eaxではなくraxになるというのは言われてみればなるほど. たまたま自分が使っていた範囲ではedxは関係が無いので気が付かなかった.
・ハロウィン
興味が無いので毎度毎度, 何を祝ってるのか調べてもすぐ忘れる. カトリックの諸聖人の日(11/1)の前夜祭.
プロテスタントが多いアメリカでは前夜祭だけ盛大にやってるらしい. やはりすぐ忘れそうだ.
#include <shlobj.h> #pragma comment(lib, "shell32.lib") #pragma comment(lib, "User32.lib") #include <stdio.h> #include <string> int main() { _putenv("SYSTEMDRIVE="); // 環境変数を消す char buf[MAX_PATH]; if (SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, 0, buf) == S_OK) { // Xp, 2003はOK printf("programdata=%s\n", buf); } else { // Vista, 2008 server, Windows 7だと動かない int err = GetLastError(); printf("err=%d\n", err); return 1; } }
#include <stdio.h> template<typename T> class X { T t_; struct DummyClass; template<typename S, void (S::*)() const> struct HasMemFunc { }; template<typename S> void dispatch(int, HasMemFunc<S, &S::func>* p = 0) { t_.func(); } template<typename S> void dispatch(DummyClass*) { puts("no func"); } public: void run() { dispatch<T>(0); } }; struct A { }; struct B { void func() const { puts("run func"); } }; int main() { X<A> a; a.run(); // "run func" X<B> b; b.run(); // "no func" }多少意味が変わるがVC専用でよければ__if_existsを使って
template<typename T> struct Y { void run() { __if_exists(T::func) { T().func(); } __if_not_exists(T::func) { puts("no func"); } } };
class BackDoor : public Xbyak::CodeGenerator { public: BackDoor(int cmd, int param) { #ifdef XBYAK32 push(ebx); push(esi); const Xbyak::Reg32& retp = esi; mov(retp, ptr [esp + 8 + 4]); #else push(rbx); const Xbyak::Reg64& retp = r8; #ifdef XBYAK64_WIN mov(retp, rcx); #else mov(retp, rdi); #endif #endif mov(eax, 0x564d5868); mov(ebx, param); mov(ecx, cmd); mov(edx, 0x5658); db(0xed); // in eax, dx mov(ptr [retp + 0], eax); mov(ptr [retp + 4], ebx); mov(ptr [retp + 8], ecx); mov(ptr [retp + 12], ecx); #ifdef XBYAK32 pop(esi); pop(ebx); #else pop(rbx); #endif ret(); }
#include <stdio.h> #include <algorithm> int main() { printf("min(3, 1)=%u\n", std::min<size_t>(3, 1)); printf("max(1, 3)=%u\n", std::max<size_t>(1, 3)); } // min(3, 1)=3 max(1, 3)=1minとmaxが逆になってるのではなく常に第1引数の値が返る. いくらβとは言え, こんな酷いバグがあったとは.
template<class _Ty, class _Pr> inline const _Ty& (min)(const _Ty& _Left, _Pr) { // return _Left as smallest return (_Left); }よくわからんところにマッチしてるなあ.
#if 1 #elif #endifがVC9やgcc 4.3.4でコンパイルできるけどgcc 4.4でエラーになる. #if 1が真となった時点で#elifの後ろの評価をしないのが正しいならgcc 4.4が間違ってるということかな. mcppのチェックでもエラーにはならなかった. 本当に殆ど何もチェックしないのでたとえば
#if 1 #elif <html>&{this}|(what)!?? #endifもgcc 4.4以外ではエラーにならなかった.
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.2 99.9 328 589505315 ? S 06:29 0:02 init [3] % uname -a Linux mie 2.6.31.3 #1 Sun Oct 11 01:29:43 JST 2009 i686 GNU/Linuxリブートしても変わらない. 何度やっても同じ. 589505315 = 0x23232323だから何か未初期化メモリを参照したのかなあ.
% free total used free shared buffers cached Mem: 1519612 246140 1273472 0 161652 47088 -/+ buffers/cache: 37400 1482212 Swap: 0 0 0だし, 触ってて特に実害はなさそうなんだけど気持ち悪い.
int func(int a, int b, int c, int d, int e) const { return x_ + y_ + a + b + c + d + e; }相当のJIT的メンバ関数はこんな感じ(memfunc.cpp). 無理に一つのソースにまとめたからやや見にくいけど
const struct { const Reg32e& self; const Operand& a; const Operand& b; const Operand& c; const Operand& d; } para = { #if defined(XBYAK64_WIN) rcx, edx, r8d, r9d, ptr [rsp + 8 * 5], ptr [rsp + 8 * 6], #elif defined(XBYAK64_GCC) rdi, esi, edx, ecx, r8d, r9d, #else ecx, ptr [esp + 4 + PARA_ADJ], ptr [esp + 8 + PARA_ADJ], ptr [esp + 12 + PARA_ADJ], ptr [esp + 16 + PARA_ADJ], ptr [esp + 20 + PARA_ADJ], #endif }; mov(eax, ptr [para.self]); add(eax, ptr [para.self + 4]); add(eax, para.a); add(eax, para.b); ...このあたりの部分はたいしたことないんだけど一見トリッキーな記述っぽくて面白い.
int (A::*p)(int, int) const = (int (A::*)(int, int) const)code.getCode();みたいにやってないのはそれが理由. class Bのメンバ関数をAのメンバ関数にキャストすることはできるのだからちょっと不思議だ.
#include <stdio.h> #include <stdlib.h> #include <xbyak/xbyak.h> struct A { int x_; int y_; A() : x_(3), y_(5) {} int func(int a, int b) const { return x_ + y_ + a + b; } }; struct Code : public Xbyak::CodeGenerator { Code() { #ifdef _WIN32 const int PARA_ADJ = 0; const int RET_ADJ = 8; #else mov(ecx, ptr [esp + 4]); const int PARA_ADJ = 4; const int RET_ADJ = 0; #endif mov(eax, ptr [ecx]); add(eax, ptr [ecx + 4]); add(eax, ptr [esp + 4 + PARA_ADJ]); add(eax, ptr [esp + 8 + PARA_ADJ]); ret(RET_ADJ); } }; int main() { Code code; int (A::*p)(int, int) const = 0; *(void**)&p = (void*)code.getCode(); for (int i = 0; i < 10; i++) { A a; int t1, t2, x, y; a.x_ = rand(); a.y_ = rand(); t1 = rand(); t2 = rand(); x = a.func(t1, t2); y = (a.*p)(t1, t2); printf("%d, %d\n", x, y); } }