[2]関数run()の直前に以下の関数群を追加
String regNamX86[8] = { "EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI" };
int modRmX86(unsigned char *p, char *s)
{
int c0 = *p;
if ((c0 & 0xc0) == 0xc0) {
strcpy(s, regNamX86[c0 & 7]);
return 1;
}
if ((c0 & 0xc7) == 0x05) {
sprintf(s, "DWORD [.%s]", ts[(IntP) get32(p + 1) - var]);
return 5;
}
if ((c0 & 0xc7) == 0x04 && p[1] == 0x8a) {
sprintf(s, "[EDX+ECX*4]");
return 2;
}
if ((c0 & 0xc7) == 0x44 && p[1] == 0x24) {
sprintf(s, "[ESP+%d]", p[2]);
return 3;
}
printf("modRmX86: error: %02x\n", c0);
exit(1);
}
String asmX86_sub1(int q, String p0, String s, String p1, String t)
// (q) 1:modRの直前の1バイトの下位3bitがレジスタを指定, 2:modRm内の中間3bitがレジスタを指定, 3:modRmを解釈した結果.
// 4:8bit即値, 5:32bit即値, 6:CL, 7:sub関数呼び出し, 8:JMP/Jccの分岐先ラベル.
{
if (q == 1) { return regNamX86[p0[-1] & 7]; }
if (q == 2) { return regNamX86[(p0[0] >> 3) & 7]; }
if (q == 3) { return s; }
if (q == 4) { sprintf(t, "%d", *((signed char *) p1)); return t; }
if (q == 6) { return "CL"; }
if (q == 8) { sprintf(t, ".%s", ts[((IntP) get32(p1)) - var]); return t; }
if (q == 5) {
int i = get32(p1), j;
sprintf(t, "%d", i);
for (j = 0; j < tcs; j++) {
if (var[j] == i && ts[j][0] == 34) {
sprintf(t, ".str%d", i);
varOpt[j] |= 2;
}
}
return t;
}
if (q == 7) {
void *sub = p1 + 4 + get32(p1);
if (sub == sub_print) { return "_sub_print"; }
if (sub == sub_time) { return "_sub_time"; }
if (sub == sub_aRgb8) { return "_sub_aRgb8"; }
if (sub == sub_XorShift) { return "_sub_XorShift"; }
if (sub == sub_aGetPix) { return "_sub_aGetPix"; }
if (sub == sub_f16Sin) { return "_sub_f16Sin"; }
if (sub == sub_f16Cos) { return "_sub_f16Cos"; }
if (sub == sub_aInkey) { return "_sub_aInkey"; }
if (sub == sub_prints) { return "_sub_prints"; }
if (sub == sub_aSetPix0) { return "_sub_aSetPix0"; }
if (sub == sub_aFilRct0) { return "_sub_aFilRct0"; }
if (sub == sub_aDrwStr0) { return "_sub_aDrwStr0"; }
if (sub == sub_gprDec) { return "_sub_gprDec"; }
if (sub == sub_OpnWin) { return "_sub_OpnWin"; }
if (sub == sub_aWait) { return "_sub_aWait"; }
if (sub == sub_bitblt) { return "_sub_bitblt"; }
if (sub == sub_aryNew) { return "_sub_aryNew"; }
if (sub == sub_aryInit) { return "_sub_aryInit"; }
}
return "?";
}
int asmX86_sub0(unsigned char *p, String op, int modRm, int q0, int q1, int q2)
// modRm: mod r/m があるかないか.
{
char s[100], t[100];
int len = 0;
String p0 = p;
if (modRm != 0) {
len = modRmX86(p, s);
p += len;
}
printf(" %-8s", op);
if (q0 > 0) {
printf("%s", asmX86_sub1(q0, p0, s, p, t));
if (q1 > 0) {
printf(",%s", asmX86_sub1(q1, p0, s, p, t));
if (q2 > 0) {
printf(",%s", asmX86_sub1(q2, p0, s, p, t));
}
}
}
printf("\n");
return len;
}
String asmX86_grp0[8] = { "ADD", "OR", "ADC", "SBB", "AND", "SUB", "XOR", "CMP" };
String asmX86_jcc[16] = { "JO", "JNO", "JB", "JAE", "JE", "JNE", "JBE", "JA", "JS", "JNS", "JP", "JNP", "JL", "JGE", "JLE", "JG" };
String asmX86_shft[8] = { "ROL", "ROR", "RCL", "RCR", "SHL", "SHR", "?", "SAR" };
void asmX86()
{
int i, j, k = 0;
printf("BITS 32\n");
printf("SECTION .text\n");
printf("GLOBAL _aMain\n");
printf(" ALIGNB 16\n");
printf("_aMain:\n");
for (i = 0; i < jp; i++) {
icq = jmps[i] + ic;
j = ((IntP) get32(icq)) - var;
varOpt[j] |= 1; // 利用したラベルをマークする.
}
for (i = 0;;) {
int c0 = ic[i], c1 = ic[i + 1];
for (j = 0; j < tcs; j++) {
if (var[j] == (AInt) i && (varOpt[j] & 1) != 0) {
printf(".%s:\n", ts[j]); // ラベル定義出力.
}
}
if (k < ailp && aryInitList[k] + 4 == i) {
printf(" MOV EAX,.ary%d\n", get32(&ic[i + 1]));
i += 5;
k++;
continue;
}
if (c0 == 0x0f) {
if (0x80 <= c1 && c1 <= 0x8f) { i += asmX86_sub0(&ic[i + 2], asmX86_jcc[c1 & 15], 0, 8, 0, 0) + 6; continue; }
if (0x90 <= c1 && c1 <= 0x9f) {
printf(" SET%-5sAL\n", asmX86_jcc[c1 & 15] + 1);
printf(" MOVZX EAX,AL\n");
i += 6;
continue;
}
if (c1 == 0xac) { i += asmX86_sub0(&ic[i + 2], "SHRD", 1, 3, 2, 4) + 3; continue; }
if (c1 == 0xad) { i += asmX86_sub0(&ic[i + 2], "SHRD", 1, 3, 2, 6) + 2; continue; }
if (c1 == 0xaf) { i += asmX86_sub0(&ic[i + 2], "IMUL", 1, 2, 3, 0) + 2; continue; }
}
if (c0 == 0x03) { i += asmX86_sub0(&ic[i + 1], "ADD", 1, 2, 3, 0) + 1; continue; }
if (c0 == 0x2b) { i += asmX86_sub0(&ic[i + 1], "SUB", 1, 2, 3, 0) + 1; continue; }
if (c0 == 0x3b) { i += asmX86_sub0(&ic[i + 1], "CMP", 1, 2, 3, 0) + 1; continue; }
if (c0 == 0x31) { i += asmX86_sub0(&ic[i + 1], "XOR", 1, 3, 2, 0) + 1; continue; }
if (0x40 <= c0 && c0 <= 0x47) { i += asmX86_sub0(&ic[i + 1], "INC", 0, 1, 0, 0) + 1; continue; }
if (0x48 <= c0 && c0 <= 0x4f) { i += asmX86_sub0(&ic[i + 1], "DEC", 0, 1, 0, 0) + 1; continue; }
if (c0 == 0x60) { i += asmX86_sub0(0, "PUSHAD", 0, 0, 0, 0) + 1; continue; }
if (c0 == 0x61) { i += asmX86_sub0(0, "POPAD", 0, 0, 0, 0) + 1; continue; }
if (c0 == 0x69) { i += asmX86_sub0(&ic[i + 1], "IMUL", 1, 2, 3, 5) + 5; continue; }
if (c0 == 0x6b) { i += asmX86_sub0(&ic[i + 1], "IMUL", 1, 2, 3, 4) + 2; continue; }
if (c0 == 0x81) { i += asmX86_sub0(&ic[i + 1], asmX86_grp0[(c1 >> 3) & 7], 1, 3, 5, 0) + 5; continue; }
if (c0 == 0x83) { i += asmX86_sub0(&ic[i + 1], asmX86_grp0[(c1 >> 3) & 7], 1, 3, 4, 0) + 2; continue; }
if (c0 == 0x85) { i += asmX86_sub0(&ic[i + 1], "TEST", 1, 3, 2, 0) + 1; continue; }
if (c0 == 0x89) { i += asmX86_sub0(&ic[i + 1], "MOV", 1, 3, 2, 0) + 1; continue; }
if (c0 == 0x8b) { i += asmX86_sub0(&ic[i + 1], "MOV", 1, 2, 3, 0) + 1; continue; }
if (c0 == 0x99) { i += asmX86_sub0(0, "CDQ", 0, 0, 0, 0) + 1; continue; }
if (0xb8 <= c0 && c0 <= 0xbf) { i += asmX86_sub0(&ic[i + 1], "MOV", 0, 1, 5, 0) + 5; continue; }
if (c0 == 0xd3) { i += asmX86_sub0(&ic[i + 1], asmX86_shft[(c1 >> 3) & 7], 1, 3, 6, 0) + 1; continue; }
if (c0 == 0xc3) { asmX86_sub0(0, "RET", 0, 0, 0, 0); break; }
if (c0 == 0xe8) { i += asmX86_sub0(&ic[i + 1], "CALL", 0, 7, 0, 0) + 5; continue; }
if (c0 == 0xe9) { i += asmX86_sub0(&ic[i + 1], "JMP", 0, 8, 0, 0) + 5; continue; }
if (c0 == 0xf7) {
c1 = (c1 >> 3) & 7;
if (c1 == 3) { i += asmX86_sub0(&ic[i + 1], "NEG", 1, 3, 0, 0) + 1; continue; }
if (c1 == 5) { i += asmX86_sub0(&ic[i + 1], "IMUL", 1, 3, 0, 0) + 1; continue; }
if (c1 == 7) { i += asmX86_sub0(&ic[i + 1], "IDIV", 1, 3, 0, 0) + 1; continue; }
}
printf("asmX86: error: %02x-%02x\n", c0, c1);
exit(1);
}
printf("EXTERN _sub_print, _sub_time, _sub_aRgb8, _sub_XorShift\n");
printf("EXTERN _sub_aGetPix, _sub_f16Sin, _sub_f16Cos, _sub_aInkey\n");
printf("EXTERN _sub_prints, _sub_aSetPix0, _sub_aFilRct0, _sub_aDrwStr0\n");
printf("EXTERN _sub_gprDec, _sub_OpnWin, _sub_aWait, _sub_bitblt\n");
printf("EXTERN _sub_aryNew, _sub_aryInit\n");
printf("SECTION .data\n");
printf(" ALIGNB 16\n");
for (j = 0; j < tcs; j++) {
if (vc[j] > 0) {
printf(".%-6s DD %d\n", ts[j], var[j]);
}
}
for (k = 0; k < ailp; k++) {
int j1 = get32(&ic[aryInitList[k] + 13]), *ip = (IntP) get32(&ic[aryInitList[k] + 5]);
printf(".ary%d:\n", (int) ip);
for (j = 0; j < j1; j++) {
printf(" DD %d\n", ip[j]);
}
}
for (j = 0; j < tcs; j++) {
if ((varOpt[j] & 2) != 0) {
printf(".str%d DD %s,0\n", var[j], ts[j]);
}
}
}