gnupic@linuxhacker.org
gnupic@linuxhacker.org
Subject: Re: gpdasm problem
From: Gabor Kiss [Bitman]
Date: Mon, 9 Feb 2004 09:05:11 +0100 (CET)
> > Assemble then disassemble this file:
> > --------------------------
> > processor p18f448
> > org 0x800
> > goto label1
> > bra label1
> > label1
> > end
> > -------------------------
> >
> > 'gpdasm-0.11.8 alpha' produces this:
> > -----------------------------
> > 000800: ef03 goto 0x806
> > 000802: f004
> > 000804: d000 bra 0x6
> > -----------------------------
> >
> > I think "bra 0x806" would be more intuitive. ;-)
> --- gpdis.c.orig 2004-01-19 07:54:15.000000000 -0600
> +++ gpdis.c 2004-01-19 07:52:05.000000000 -0600
> @@ -124,10 +124,10 @@
> DECODE_ARG1(opcode & 0x1fff);
> break;
> case INSN_CLASS_RBRA8:
> - DECODE_ARG1((((opcode & 0xff) + (*org + 1)) * 2) & 0xff);
> + DECODE_ARG1((((opcode & 0xff) + (*org + 1)) * 2));
> break;
> case INSN_CLASS_RBRA11:
> - DECODE_ARG1((((opcode & 0x7ff) + (*org + 1)) * 2) & 0x7ff);
> + DECODE_ARG1((((opcode & 0x7ff) + (*org + 1)) * 2));
> break;
> case INSN_CLASS_LIT20:
> {
Further problem: the 8/11 bit displacement is a 2's complement
value. The simple masking above turns it into unsigned.
This patch solves the problem.
Gabor
--- gpdis.c.orig Fri Mar 14 07:44:51 2003
+++ gpdis.c Sun Feb 8 14:14:46 2004
@@ -124,10 +124,13 @@
DECODE_ARG1(opcode & 0x1fff);
break;
case INSN_CLASS_RBRA8:
- DECODE_ARG1((((opcode & 0xff) + (*org + 1)) * 2) & 0xff);
+#define unwanted(bits) (sizeof(long)*8-(bits))
+#define displacement(opcode,bits) (((signed long)((opcode)<<unwanted(bits))) / \
+ (1<<unwanted(bits)))
+ DECODE_ARG1(((displacement(opcode,8) + (*org + 1)) * 2));
break;
case INSN_CLASS_RBRA11:
- DECODE_ARG1((((opcode & 0x7ff) + (*org + 1)) * 2) & 0x7ff);
+ DECODE_ARG1(((displacement(opcode,11) + (*org + 1)) * 2));
break;
case INSN_CLASS_LIT20:
{
gnupic@linuxhacker.org