gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

ASM > devkitARM and .s files problem

#58571 - t81b - Mon Oct 24, 2005 5:39 pm

hello,

I've been trying to move a project over to devkitarm from devkitadv but I've run into a couple of problems with .s files.
I think I've tracked one problem down to branch commands not jumping to the correct address when I use the .global directive for a symbol.
Below is a small snippet of code demonstrating the problem.

Code:

   .thumb_func
   .global   back
back:   b   for
   
   .thumb_func
   .global for
for:   b   back


Now this works without problems in devkitadv, but with devkitARM the branch commands point to the wrong addresses, so could there be something wrong with devkitARM or AS, or am I doing something wrong?

If I leave out the globals it works ok but I need to use them, and I could get around the problem by doing the following, so that branches within a file jump to a different label but the same address (but I'd have quite a few files to go through so I'd rather not have to do this :) )

Code:

   .thumb_func
   .global   back
back:
back2:   b   for2
   
   .thumb_func
   .global for
for:
for2:   b   back2



The other problem is to do with devkitarm not being able to find .include files unless I give the absolute path such as:

Code:
.include "e:/project/source/hardware.inc"


rather than

Code:
.include "hardware.inc"



I can get around this by replacing the following lines in the base_rules:

Code:

#---------------------------------------------------------------------------------
%.o: %.s
   @echo $(notdir $<)
   @$(CC) -MMD -MF $(DEPSDIR)/$*.d -x assembler-with-cpp $(ASFLAGS) -c $< -o $@
   @$(adjustdepends)


with this :

Code:

#---------------------------------------------------------------------------------
%.o: %.s
   @echo $(notdir $<)
   @$(AS) $(ASFLAGS) $< -o $@


but I'd rather not go messing with the base_rules file if I can avoid it.


Any ideas on what I'm doing wrong or how to fix this?
I'm using the latest version of devkitarm.

Thanks, Brendan

#58574 - poslundc - Mon Oct 24, 2005 6:08 pm

This looks like it could be an alignment problem... try adding the following lines before both labels:

.align 2

Also, make sure that the assembler is generating thumb code (I'm not certain that the thumb_func directive sets that flag) by placing the following at the beginning:

.thumb

Dan.

#58611 - t81b - Mon Oct 24, 2005 9:54 pm

No, it's not that. I did have these set and should've included them with the example.

Here is a complete file and the disassembly from no$gba which shows the problem better.

I tried moving the updatePlayerDir routine to the top of the file but that made no difference.

Brendan.

Code:

   .include   "defines.s"

@ face_forward
@ set_plr_direction
   
   .text
   .thumb
   .align 4
   
   .thumb_func
   .global   face_forward
face_forward:
   mov   r5,#plr_playdir
   ldrh   r1,[r0,r5]
   cmp   r1,#0
   beq   1f         @ playing_up
   
   @===========================
   @ playing down
   @===========================

   mov   r5,#PLR_DIR_TO
    mov   r1,#4
    strh   r1,[r0,r5]
    b   updatePlayerDir      @ THIS JUMPS TO THE WRONG ADDRESS
    
   @===========================
   @ playing up
   @===========================

1:
   mov   r5,#PLR_DIR_TO
   mov   r1,#0
   strh   r1,[r0,r5]
   b   updatePlayerDir      @ THIS JUMPS TO THE WRONG ADDRESS


      

@=========================================================
@ set the direction of the player depending on his angle
@=========================================================

   @set the direction

    .thumb_func
    .global   set_plr_direction
set_plr_direction:
   ldrh   r2,[r0,#plr_angle]
   mov   r3,#0            @direction
   mov   r1,#64   @45
   cmp   r2,r1
   ble   1f   
   mov   r3,#2
   mov   r1,#192   @135
   cmp   r2,r1
   ble   1f   
   mov   r3,#4
   ldr   r1,=320   @225
   cmp   r2,r1
   ble   1f   
   mov   r3,#6
   ldr   r1,=448   @315
   cmp   r2,r1
   ble   1f   
   mov   r3,#0
1:

   mov   r5,#PLR_DIR_TO
   strh   r3,[r0,r5]
   b   updatePlayerDir      @ THIS JUMPS TO THE WRONG ADDRESS
   

   
@================================
@ turn until player is facing the correct way
@================================
@ entry:
@   r0 = player data address

   .thumb_func
   .global updatePlayerDir
updatePlayerDir:
   mov   r3,#PLR_DIR_TO
   ldrh   r1,[r0,r3]
   ldrh   r2,[r0,#PLR_DIR]
   sub   r1,r2
   beq   9f               @ facing the correct way
   bge   1f               @ turn right
   
   @ turn left
   mvn   r1,r1
   add   r1,#1
   cmp   r1,#4
   bge   2f               @ quicker to turn right

4:
   sub   r2,#1
   bge   3f
   add   r2,#8
3:
   strh   r2,[r0,#PLR_DIR]
   mov   pc,lr
   
1:
   @ turn right
   cmp   r1,#4
   bge   4b               @ quicker to turn left

2:
   add   r2,#1
   cmp   r2,#8
   blt   3f
   sub   r2,#8
3:
   strh   r2,[r0,#PLR_DIR]
9:
   mov   pc,lr

   .pool
   


Code:

face_forward:
    080BCBA0 (T)  mov     r5,40h                                  ;3  274
    080BCBA2 (T)  ldrh    r1,[r0,r5]                              ;7  281
    080BCBA4 (T)  cmp     r1,0h                                   ;3  284
    080BCBA6 (T)  beq     80BCBB0h                                ;11 295
    080BCBA8 (T)  mov     r5,4Ch                                  ;3  298
    080BCBAA (T)  mov     r1,4h                                   ;3  301
    080BCBAC (T)  strh    r1,[r0,r5]                              ;8  309
    080BCBAE (T)  b       80BCBD4h   THIS SHOULD BRANCH TO updatePlayerDir ;11 320
    080BCBB0 (T)  mov     r5,4Ch                                  ;3  323
    080BCBB2 (T)  mov     r1,0h                                   ;3  326
    080BCBB4 (T)  strh    r1,[r0,r5]                              ;8  334
    080BCBB6 (T)  b       80BCBCCh   THIS SHOULD BRANCH TO updatePlayerDir ;11 345
set_plr_direction:
    080BCBB8 (T)  ldrh    r2,[r0,1Ch]                             ;7  352
    080BCBBA (T)  mov     r3,0h                                   ;3  355
    080BCBBC (T)  mov     r1,40h                                  ;3  358
    080BCBBE (T)  cmp     r2,r1                                   ;3  361
    080BCBC0 (T)  ble     80BCBDCh                                ;11 372
    080BCBC2 (T)  mov     r3,2h                                   ;3  375
    080BCBC4 (T)  mov     r1,0C0h                                 ;3  378
    080BCBC6 (T)  cmp     r2,r1                                   ;3  381
    080BCBC8 (T)  ble     80BCBDCh                                ;11 392
    080BCBCA (T)  mov     r3,4h                                   ;3  395
    080BCBCC (T)  ldr     r1,=140h                                ;12 407
    080BCBCE (T)  cmp     r2,r1                                   ;3  410
    080BCBD0 (T)  ble     80BCBDCh                                ;11 421
    080BCBD2 (T)  mov     r3,6h                                   ;3  424
    080BCBD4 (T)  ldr     r1,=1C0h                                ;12 436
    080BCBD6 (T)  cmp     r2,r1                                   ;3  439
    080BCBD8 (T)  ble     80BCBDCh                                ;11 450
    080BCBDA (T)  mov     r3,0h                                   ;3  453
    080BCBDC (T)  mov     r5,4Ch                                  ;3  456
    080BCBDE (T)  strh    r3,[r0,r5]                              ;8  464
    080BCBE0 (T)  b       80BCBA2h  THIS SHOULD BRANCH TO updatePlayerDir  ;11 475
updatePlayerDir:
    080BCBE2 (T)  mov     r3,4Ch                                  ;3  478
    080BCBE4 (T)  ldrh    r1,[r0,r3]                              ;7  485
    080BCBE6 (T)  ldrh    r2,[r0,36h]                             ;7  492
    080BCBE8 (T)  sub     r1,r1,r2                                ;3  495
    080BCBEA (T)  beq     80BCC0Eh                                ;11 506
    080BCBEC (T)  bge     80BCC00h                                ;11 517
    080BCBEE (T)  mvn     r1,r1                                   ;3  520
    080BCBF0 (T)  add     r1,1h                                   ;3  523
    080BCBF2 (T)  cmp     r1,4h                                   ;3  526
    080BCBF4 (T)  bge     80BCC04h                                ;11 537
    080BCBF6 (T)  sub     r2,1h                                   ;3  540
    080BCBF8 (T)  bge     80BCBFCh                                ;11 551
    080BCBFA (T)  add     r2,8h                                   ;3  554
    080BCBFC (T)  strh    r2,[r0,36h]                             ;8  562
    080BCBFE (T)  mov     r15,r14                                 ;3  565
    080BCC00 (T)  cmp     r1,4h                                   ;3  568
    080BCC02 (T)  bge     80BCBF6h                                ;11 579
    080BCC04 (T)  add     r2,1h                                   ;3  582
    080BCC06 (T)  cmp     r2,8h                                   ;3  585
    080BCC08 (T)  blt     80BCC0Ch                                ;11 596
    080BCC0A (T)  sub     r2,8h                                   ;3  599
    080BCC0C (T)  strh    r2,[r0,36h]                             ;8  607
    080BCC0E (T)  mov     r15,r14                                 ;3  610

#58622 - poslundc - Mon Oct 24, 2005 10:45 pm

Try inserting .align directives between your functions, and see how it goes then.

Dan.

#58675 - wintermute - Tue Oct 25, 2005 8:06 am

The handy thing about using the -x assembler-with-cpp option is that you get to use the C Preprocessor. That means #define and #include amongst other things.

As for the incorrect branches, that's just weird. It seems to work fine with arm code and with functions that aren't made global in general. Looks like it's a problem with a recent GAS patch I made. Release 16a seems to work fine whereas r17 has the problem you describe. It should be sufficient to replace the bin/arm-elf-as and arm-elf/bin/as binaries with theire counterparts from r16a.

#58732 - t81b - Tue Oct 25, 2005 5:01 pm

Quote:
Try inserting .align directives between your functions, and see how it goes then.

Dan.


Tried this but no luck.

Quote:
As for the incorrect branches, that's just weird. It seems to work fine with arm code and with functions that aren't made global in general. Looks like it's a problem with a recent GAS patch I made. Release 16a seems to work fine whereas r17 has the problem you describe. It should be sufficient to replace the bin/arm-elf-as and arm-elf/bin/as binaries with theire counterparts from r16a.


No luck with this either, the same thing happens.
Looking at the addresses the branches are pointing to, I think I can see what is happening.
It looks like the distance of the branch is the right length but instead of adding that distance to the address where the branch command is, it is always adding the distance to the address at the start of the file. Maybe this will be of some use in helping to find a fix.


Quote:
The handy thing about using the -x assembler-with-cpp option is that you get to use the C Preprocessor. That means #define and #include amongst other things.


That does sound useful. Didn't realise I could do that. But does that mean I will still have to change the base_rules so I can find the .include files?

Brendan