EmbDev.net

Forum: ARM programming with GCC/GNU tools "Debugger"-like jumping in code


von Andy K. (horizonandy)


Rate this post
useful
not useful
I am working on a mini-debugger of sorts, and I'm needing some help on
even where to look to find an answer.  I must be asking Google the wrong
question.

What I want to do is give a command line that causes the processor to
jump to the address I specify.  I can handle the parsing, that's not the
question.

If I were doing this on a Z-80 it would be a no brainer, but ARM (using
IAR) has me boggled.  In Z-80, I would:

.      ld    HL,retaddr ; where i want execution to come back to (below)
.      push  HL
.      ld    HL,(targetaddr) ; where user specified to jump to
.      push  HL
.      ret           ; sends me to the targetaddr
retaddr:             ; normal code continues here
.      goto  cmdinput

What I want is to accomplish the same end result from both ARM and THUMB
mode (it's easy to have two functions arm_jump_to(UINT32 address) and
thumb_jumpto(UINT32 address) to do this).

Anybody have experience with how to write that for ARM assembly?

Thanks!

Andy

von Clifford S. (clifford)


Rate this post
useful
not useful
Andy Kunz wrote:
>
> Anybody have experience with how to write that for ARM assembly?

I don't have a direct answer for you (because I'd have to do some
research to figure it out), but that research would involve
understanding the ARM-THUMB Procedure Sall Standard
(www.cs.cornell.edu/courses/cs414/2001fa/armcallconvention.pdf)

Also the Hitex "Insider Guides" might be useful
http://www.hitex.co.uk/download.html

Either way, I believe the 'trick' will involve manipulation of the LR
link register.

Clifford

von Giovanni D. (gdisirio)


Rate this post
useful
not useful
Andy Kunz wrote:
> I am working on a mini-debugger of sorts, and I'm needing some help on
> even where to look to find an answer.  I must be asking Google the wrong
> question.
>
> What I want to do is give a command line that causes the processor to
> jump to the address I specify.  I can handle the parsing, that's not the
> question.
>
> If I were doing this on a Z-80 it would be a no brainer, but ARM (using
> IAR) has me boggled.  In Z-80, I would:
>
> .      ld    HL,retaddr ; where i want execution to come back to (below)
> .      push  HL
> .      ld    HL,(targetaddr) ; where user specified to jump to
> .      push  HL
> .      ret           ; sends me to the targetaddr
> retaddr:             ; normal code continues here
> .      goto  cmdinput
>
> What I want is to accomplish the same end result from both ARM and THUMB
> mode (it's easy to have two functions arm_jump_to(UINT32 address) and
> thumb_jumpto(UINT32 address) to do this).
>
> Anybody have experience with how to write that for ARM assembly?
>
> Thanks!
>
> Andy

You need to load the "LR" register with the return address, then load
another register (as example R0) with the "targetaddr" and use "BX R0"
to jump to the targetaddr.

ldr LR,=retaddr
ldr R0,=targetaddr
bx R0

The BX instruction can jump to both ARM and THUMB code but the invoked
function should use the BX instruction in order to return too (this
makes it possible to return to both ARM and THUMB code).

BTW, the Z80 has a "jmp (hl)" instruction, there is no need to push the
address and return.

regards,
Giovanni
---
ChibiOS/RT http://chibios.sourceforge.net

von Andy K. (horizonandy)


Rate this post
useful
not useful
Giovanni Di Sirio wrote:
> You need to load the "LR" register with the return address, then load
> another register (as example R0) with the "targetaddr" and use "BX R0"
> to jump to the targetaddr.
>
> ldr LR,=retaddr
> ldr R0,=targetaddr
> bx R0
>
> The BX instruction can jump to both ARM and THUMB code but the invoked
> function should use the BX instruction in order to return too (this
> makes it possible to return to both ARM and THUMB code).

Excellent, thank you!

> BTW, the Z80 has a "jmp (hl)" instruction, there is no need to push the
> address and return.

True, unless I am using HL to pass parameters to the subroutine (usually
HL and A).  This also allows me to standardize the calling format w/o
corrupting F.

Andy

von Andy K. (horizonandy)


Rate this post
useful
not useful
> ldr LR,=retaddr
> ldr R0,=targetaddr
> bx R0

Conceptually easy, but something isn't liking it.

Here's my code

  UINT32 jump_target;
...
jump_target is set to the value keyed by the user, then we attempt to
call it:
...
  // assembly to jp to (jump_target)
  asm (" LDR LR,=retn_target");
  asm (" LDR R0,jump_target");
  asm (" BX  R0");
  asm ("retn_target:");

IAR isn't like the first line (but no description of the error).  For
sake of trying to test the rest, I commented it out.  The assembly was
accepted, but it didn't link, giving the message:

Error[e18]: Range error, Expression out of range
  Where $ = retn_target + 0x100EBF  [0x100EE6]
            in module "saxparse"
(C:\d\100001\00.01\Debug\Obj\saxparse.r79),
            offset 0x22 in segment part 32, segment CODE
  What: (sector + 0x14) - (($ + 4) & 0xFFFFFFFC) >> 2 [0x3FC61]
  Allowed range: 0x0 - 0xFF
  Operand: jump_target [0x20006c]
           in module saxparse
(C:\d\100001\00.01\Debug\Obj\saxparse.r79),
           Offset 0x14 in segment part 2, segment DATA_Z

If I'm interpreting this correctly (which is highly suspect), it is
saying that it can't access the jump_target variable.  Why is that?  Is
it because I need to do something with base+offset type addressing?

Thanks.

Andy

von Giovanni D. (gdisirio)


Rate this post
useful
not useful
I don't know about IAR, that code compiles under GCC, probably a
difference in the assembler, you should read the specific documentation.

You can try something like:
1
        ldr LR, _retaddr
2
        ldr R0, _targetaddr
3
        bx R0
4
.
5
.
6
.
7
_retaddr:
8
        .word retaddr
9
_targetaddr:
10
        .word targetaddr

Note that _retaddr and _tagetaddr must be "close" to the instructions,
within the same segment.

As example, this is the startup code I use in the ARM7 demos in my
project:
1
.section vectors
2
.code 32
3
.balign 4
4
/*
5
 * System entry points.
6
 */
7
_start:
8
        ldr     pc, _reset
9
        ldr     pc, _undefined
10
        ldr     pc, _swi
11
        ldr     pc, _prefetch
12
        ldr     pc, _abort
13
        nop
14
        ldr     pc, [pc,#-0xFF0]        /* VIC - IRQ Vector Register */
15
        ldr     pc, _fiq
16
17
_reset:
18
        .word   ResetHandler
19
_undefined:
20
        .word   UndHandler
21
_swi:
22
        .word   SwiHandler
23
_prefetch:
24
        .word   PrefetchHandler
25
_abort:
26
        .word   AbortHandler
27
_fiq:
28
        .word   FiqHandler
29
        .word   0
30
        .word   0

Giovanni
---
ChibiOS/RT http://chibios.sourceforge.net

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.