Commits

Anonymous committed 7cf7433

Improved modrm tester a lot. Now takes hex string argument

Comments (0)

Files changed (2)

C/OperandDecoder.c

 {
     operandspec_t decoded;
     unsigned char mod,reg,rm,scale,index,base;
+    unsigned char* origmodrm;
 
     register unsigned int effadd;
 
     rm  = (*modRM & 0x07);
 
     decoded.destReg = (xmmregister_t) reg;
+    decoded.bytesToSkip = 0;
 
     if (mod == 3) { // 11b
         decoded.sourceIsRegister = 1;
 
     if (rm == 4) { // SIB
         modRM++;
+        decoded.bytesToSkip++;
 
         scale = (*modRM       ) >> 6;
         index = (*modRM & 0x38) >> 3;
         effadd <<= scale;
         if (mod != 0) effadd += regs->reg[7 - base];
     }
-    else if (rm == 5 && mod == 0)
+    else if (rm == 5 && mod == 0) {
         effadd = disp32(++modRM);
+        decoded.bytesToSkip++;
+    }
     else
         effadd = regs->reg[7 - rm];
 
-    if (mod == 1) effadd += disp8(++modRM);
-    if (mod == 2) effadd += disp32(++modRM);
+    if (mod == 1) { effadd += disp8(++modRM); decoded.bytesToSkip++; }
+    if (mod == 2) { effadd += disp32(++modRM); decoded.bytesToSkip+=4; }
 
     decoded.sourceMem = (void*) effadd;
     decoded.sourceIsRegister = 0;

C/Test_OperandDecoder.c

 #include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
 #include "OperandDecoder.c"
 
-int main() {
+int val(char c) {
+    if (48 <= c && c <= 57) // digits
+        return c-48;
+    if (65 <= c && c <= 70) // capital A-F
+        return (c-65)+10;
+    if (97 <= c && c <= 102) // small a-f
+        return (c-97)+10;
+}
+
+char* getchararray(char* c) {
+    int l = strlen(c);
+    int i, j = 0;
+    char* res = malloc(l/2);
+    printf("Input = { ");
+    for (i = 0; i < l; i=i+2) {
+        res[j] = val(c[i]) * 16 + val(c[i+1]);
+        printf("0x%c%c ", c[i],c[i+1]);
+        j++;
+    }
+    printf("}\n", res);
+    return res;
+}
+
+int main(int argc, char* argv[]) {
     registers_t regs;
     int i;
-    unsigned char modRM[] = { 0x04, 0x20, 0xff, 0x00, 0x00, 0x00 };
+    unsigned char* modRM;
+    if (argc > 1) modRM = (unsigned char*) getchararray(argv[1]);
+    else modRM = (unsigned char*) getchararray("C0");
+
     unsigned long long starttime, endtime;
     operandspec_t op;
     for (i = 0; i <= 7; i++)
-        regs.reg[i] = 7-i;
+        regs.reg[i] = pow(2,i);
 
     asm ("rdtsc\n" : "=A"(starttime));
     for (i = 1; i < 1000000; i++)
 
     printf("Source  = %s%x\n", op.sourceIsRegister ? "reg xmm" : "mem 0x", op.sourceMem);
     printf("Dest    = reg xmm%u\n", op.destReg);
-    printf("Cycles  = %u\n", (endtime - starttime) / i);
+    printf("Read    = %d bytes incl. modrm\n", op.bytesToSkip + 1);
+    printf("Cycles  = %u / decode\n", (endtime - starttime) / i);
+
+    if (!modRM) free(modRM);
 
     return 0;
 }