The output of gen predicted the output of gas. ie. gen illustrates how to construct the REX and MODRM bytes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
$ cat gen.c typedef unsigned char C, *S; typedef int I; I printf (S, ...); I e (C x) { printf ("%x ", x); } I a (C i, I x, I y, I z) { C m[] = "ma", o[] = { 0x89, 0x01, 0 }; C rex (C x, C y) { return 0x48 + (x > 7) * 4 + (y > 7); } C modrm (C x, C y) { return 0xc0 + (x & 7) * 8 + (y & 7); } I ins (I i, C x, C y) { return e (rex (x, y)), e (o[i]), e (modrm (x, y)); } ins (i, x, y); printf ("\n"); } S r[] = { "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 0 }; int main () { printf ("\tmov %%%s,%%%s # the assembler will emit: ", r[5], r[9]); a (0, 5, 9, 0); printf ("\tadd %%%s,%%%s # the assembler will emit: ", r[9], r[9]); a (1, 9, 9, 0); } |
1 2 3 4 5 6 7 8 9 |
$ gcc gen.c -o gen $ ./gen > out.s $ cat out.s mov %rbp,%r9 # the assembler will emit: 49 89 e9 add %r9,%r9 # the assembler will emit: 4d 1 c9 $ as out.s -o out $ objdump -d out |tail -2 0: 49 89 e9 mov %rbp,%r9 3: 4d 01 c9 add %r9,%r9 |
the output of gen predicted output of gas. ie. gen illustrates how to construct the REX and MODRM bytes