This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
objdump: i386 nasm-like output
- To: binutils at sourceware dot cygnus dot com
- Subject: objdump: i386 nasm-like output
- From: Matthias Kramm <matthias dot kramm at stud dot tu-muenchen dot de>
- Date: Fri, 27 Jul 2001 12:47:21 +0200
Hi all.
I poked around a little bit in objdump in order to achieve a disassembly output
which is similar to the netwide assembler (nasm) format.
I.e.. I did want to have
mov ax,0x10
mov [ds:bx+di],al
add bx,0x1
instead of objdump's standard
mov $0x10,%ax
mov %al,%ds:(%bx,%di)
add $0x1,%bx
as diassembly output.
I discovered -m i386:intel does a subset of what I wanted, at least it
swaps the registers ($0x10,%ax -> %ax,$0x10).
Also, I wrote a patch to get rid of the '%'s, '$'s and change
[bx,di] to [bx+di], which is actually sufficient to achieve
an output in the format described above.
Are my changes to objdump (actually, libopcodes) interesting
for a broader audience? Programmers coming from dos or windows
systems are mostly used to nasm-like assemblers, like tasm or masm
which use exactly the format above.
The patch in question is applied. I was wondering whether
the decision how to disassemble should be implemented in
a different way. At the moment, the patch simply overloads
the i386:intel machine format.
Should one...
(a) introduce a new machine format (objdump -m)?
(b) use an disassembly option, which selects, for intel-architectures,
which format to use? (objdump -M)
(c) Leave libopcodes alone, and only change objdump.c (I.e. filter the
output from the disassembler-function), introducing
a new objdump command line option?
Any help is much appreciated.
Greetings
Matthias
Index: i386-dis.c
===================================================================
RCS file: /cvs/src/src/opcodes/i386-dis.c,v
retrieving revision 1.28
diff -u -r1.28 i386-dis.c
--- i386-dis.c 2001/07/18 13:33:12 1.28
+++ i386-dis.c 2001/07/27 10:43:26
@@ -1132,29 +1132,63 @@
need to update onebyte_has_modrm or twobyte_has_modrm. */
#define MODRM_CHECK if (!need_modrm) abort ()
-static const char *names64[] = {
+static const char **names64;
+static const char **names32;
+static const char **names16;
+static const char **names8;
+static const char **names8rex;
+static const char **names_seg;
+static const char **index16;
+
+static const char *nasm_names64[] = {
+ "rax","rcx","rdx","rbx", "rsp","rbp","rsi","rdi",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
+};
+static const char *nasm_names32[] = {
+ "eax","ecx","edx","ebx", "esp","ebp","esi","edi",
+ "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
+};
+static const char *nasm_names16[] = {
+ "ax","cx","dx","bx","sp","bp","si","di",
+ "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
+};
+static const char *nasm_names8[] = {
+ "al","cl","dl","bl","ah","ch","dh","bh",
+};
+static const char *nasm_names8rex[] = {
+ "al","cl","dl","bl","spl", "bpl", "sil", "dil",
+ "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
+};
+static const char *nasm_names_seg[] = {
+ "es","cs","ss","ds","fs","gs","?","?",
+};
+static const char *nasm_index16[] = {
+ "bx+si","bx+di","bp+si","bp+di","si","di","bp","bx"
+};
+
+static const char *standard_names64[] = {
"%rax","%rcx","%rdx","%rbx", "%rsp","%rbp","%rsi","%rdi",
"%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
};
-static const char *names32[] = {
+static const char *standard_names32[] = {
"%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
"%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
};
-static const char *names16[] = {
+static const char *standard_names16[] = {
"%ax","%cx","%dx","%bx","%sp","%bp","%si","%di",
"%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
};
-static const char *names8[] = {
+static const char *standard_names8[] = {
"%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh",
};
-static const char *names8rex[] = {
+static const char *standard_names8rex[] = {
"%al","%cl","%dl","%bl","%spl", "%bpl", "%sil", "%dil",
"%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
};
-static const char *names_seg[] = {
+static const char *standard_names_seg[] = {
"%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
};
-static const char *index16[] = {
+static const char *standard_index16[] = {
"%bx,%si","%bx,%di","%bp,%si","%bp,%di","%si","%di","%bp","%bx"
};
@@ -1800,6 +1834,7 @@
* The function returns the length of this instruction in bytes.
*/
+static char intel_nasm;
static char intel_syntax;
static char open_char;
static char close_char;
@@ -1812,6 +1847,14 @@
disassemble_info *info;
{
intel_syntax = 0;
+ intel_nasm = 0;
+ names64=standard_names64;
+ names32=standard_names32;
+ names16=standard_names16;
+ names8=standard_names8;
+ names8rex=standard_names8rex;
+ names_seg=standard_names_seg;
+ index16=standard_index16;
open_char = '(';
close_char = ')';
separator_char = ',';
@@ -1826,6 +1869,14 @@
disassemble_info *info;
{
intel_syntax = 1;
+ intel_nasm = 1;
+ names64=nasm_names64;
+ names32=nasm_names32;
+ names16=nasm_names16;
+ names8=nasm_names8;
+ names8rex=nasm_names8rex;
+ names_seg=nasm_names_seg;
+ index16=nasm_index16;
open_char = '[';
close_char = ']';
separator_char = '+';
@@ -2449,7 +2500,10 @@
int bytemode ATTRIBUTE_UNUSED;
int sizeflag ATTRIBUTE_UNUSED;
{
+ if(intel_nasm)
sprintf (scratchbuf, "%%st(%d)", rm);
+ else
+ sprintf (scratchbuf, "st(%d)", rm);
oappend (scratchbuf);
}
@@ -2755,31 +2809,49 @@
{
if (prefixes & PREFIX_CS)
{
- oappend ("%cs:");
+ if(intel_nasm)
+ oappend ("cs:");
+ else
+ oappend ("%cs:");
used_prefixes |= PREFIX_CS;
}
if (prefixes & PREFIX_DS)
{
+ if(intel_nasm)
+ oappend ("ds:");
+ else
oappend ("%ds:");
used_prefixes |= PREFIX_DS;
}
if (prefixes & PREFIX_SS)
{
+ if(intel_nasm)
+ oappend ("ss:");
+ else
oappend ("%ss:");
used_prefixes |= PREFIX_SS;
}
if (prefixes & PREFIX_ES)
{
+ if(intel_nasm)
+ oappend ("es:");
+ else
oappend ("%es:");
used_prefixes |= PREFIX_ES;
}
if (prefixes & PREFIX_FS)
{
+ if(intel_nasm)
+ oappend ("fs:");
+ else
oappend ("%fs:");
used_prefixes |= PREFIX_FS;
}
if (prefixes & PREFIX_GS)
{
+ if(intel_nasm)
+ oappend ("gs:");
+ else
oappend ("%gs:");
used_prefixes |= PREFIX_GS;
}
@@ -3269,7 +3341,10 @@
switch (code)
{
case indir_dx_reg:
- s = "(%dx)";
+ if(intel_nasm)
+ s = "(dx)";
+ else
+ s = "(%dx)";
break;
case ax_reg: case cx_reg: case dx_reg: case bx_reg:
case sp_reg: case bp_reg: case si_reg: case di_reg:
@@ -3324,7 +3399,10 @@
switch (code)
{
case indir_dx_reg:
- s = "(%dx)";
+ if(intel_nasm)
+ s = "(dx)";
+ else
+ s = "(%dx)";
break;
case ax_reg: case cx_reg: case dx_reg: case bx_reg:
case sp_reg: case bp_reg: case si_reg: case di_reg:
@@ -3409,8 +3487,8 @@
op &= mask;
scratchbuf[0] = '$';
- print_operand_value (scratchbuf + !intel_syntax, 1, op);
- oappend (scratchbuf);
+ print_operand_value (scratchbuf + (intel_nasm || !intel_syntax), 1, op);
+ oappend (scratchbuf + intel_nasm);
scratchbuf[0] = '\0';
}
@@ -3462,8 +3540,8 @@
op &= mask;
scratchbuf[0] = '$';
- print_operand_value (scratchbuf + !intel_syntax, 1, op);
- oappend (scratchbuf);
+ print_operand_value (scratchbuf + (intel_nasm || !intel_syntax), 1, op);
+ oappend (scratchbuf + intel_nasm);
scratchbuf[0] = '\0';
}
@@ -3515,7 +3593,7 @@
scratchbuf[0] = '$';
print_operand_value (scratchbuf + 1, 1, op);
- oappend (scratchbuf);
+ oappend (scratchbuf + intel_nasm);
}
static void
@@ -3565,7 +3643,7 @@
"%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
};
- oappend (sreg[reg]);
+ oappend (sreg[reg]+intel_nasm);
}
static void
@@ -3586,7 +3664,10 @@
seg = get16 ();
}
used_prefixes |= (prefixes & PREFIX_DATA);
- sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
+ if(intel_nasm)
+ sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
+ else
+ sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
oappend (scratchbuf);
}
@@ -3670,7 +3751,10 @@
int code;
int sizeflag;
{
- oappend ("%es:");
+ if(intel_nasm)
+ oappend ("es:");
+ else
+ oappend ("%es:");
ptr_reg (code, sizeflag);
}
@@ -3700,7 +3784,10 @@
USED_REX (REX_EXTX);
if (rex & REX_EXTX)
add = 8;
- sprintf (scratchbuf, "%%cr%d", reg+add);
+ if(intel_nasm)
+ sprintf (scratchbuf, "cr%d", reg+add);
+ else
+ sprintf (scratchbuf, "%%cr%d", reg+add);
oappend (scratchbuf);
}
@@ -3713,7 +3800,10 @@
USED_REX (REX_EXTX);
if (rex & REX_EXTX)
add = 8;
- sprintf (scratchbuf, "%%db%d", reg+add);
+ if(intel_nasm)
+ sprintf (scratchbuf, "db%d", reg+add);
+ else
+ sprintf (scratchbuf, "%%db%d", reg+add);
oappend (scratchbuf);
}
@@ -3722,7 +3812,10 @@
int dummy ATTRIBUTE_UNUSED;
int sizeflag ATTRIBUTE_UNUSED;
{
- sprintf (scratchbuf, "%%tr%d", reg);
+ if(intel_nasm)
+ sprintf (scratchbuf, "tr%d", reg);
+ else
+ sprintf (scratchbuf, "%%tr%d", reg);
oappend (scratchbuf);
}
@@ -3748,9 +3841,19 @@
add = 8;
used_prefixes |= (prefixes & PREFIX_DATA);
if (prefixes & PREFIX_DATA)
- sprintf (scratchbuf, "%%xmm%d", reg + add);
+ {
+ if(intel_nasm)
+ sprintf (scratchbuf, "xmm%d", reg + add);
+ else
+ sprintf (scratchbuf, "%%xmm%d", reg + add);
+ }
else
- sprintf (scratchbuf, "%%mm%d", reg + add);
+ {
+ if(intel_nasm)
+ sprintf (scratchbuf, "mm%d", reg + add);
+ else
+ sprintf (scratchbuf, "%%mm%d", reg + add);
+ }
oappend (scratchbuf);
}
@@ -3763,7 +3866,11 @@
USED_REX (REX_EXTX);
if (rex & REX_EXTX)
add = 8;
- sprintf (scratchbuf, "%%xmm%d", reg + add);
+ if(intel_nasm)
+ sprintf (scratchbuf, "xmm%d", reg + add);
+ else
+ sprintf (scratchbuf, "%%xmm%d", reg + add);
+
oappend (scratchbuf);
}
@@ -3787,9 +3894,19 @@
codep++;
used_prefixes |= (prefixes & PREFIX_DATA);
if (prefixes & PREFIX_DATA)
- sprintf (scratchbuf, "%%xmm%d", rm + add);
+ {
+ if(intel_nasm)
+ sprintf (scratchbuf, "xmm%d", rm + add);
+ else
+ sprintf (scratchbuf, "%%xmm%d", rm + add);
+ }
else
- sprintf (scratchbuf, "%%mm%d", rm + add);
+ {
+ if(intel_nasm)
+ sprintf (scratchbuf, "mm%d", rm + add);
+ else
+ sprintf (scratchbuf, "%%mm%d", rm + add);
+ }
oappend (scratchbuf);
}
@@ -3811,7 +3928,10 @@
/* skip mod/rm byte */
MODRM_CHECK;
codep++;
- sprintf (scratchbuf, "%%xmm%d", rm + add);
+ if(intel_nasm)
+ sprintf (scratchbuf, "xmm%d", rm + add);
+ else
+ sprintf (scratchbuf, "%%xmm%d", rm + add);
oappend (scratchbuf);
}