Jump to content

Giant Case Statement Generates Labels That Are Too Far For Bra

Recommended Posts

Bug description:

If the label for a branch (BRA) is too far away, no error is generated but instead the distance is truncated resulting in a branch to a bogus location.


Steps to reproduce:

See below in comments. I also attached the project


Expected behaviour:

The assembler should have produced an error or better yet, the compiler/linker should have generated a goto instruction since it has a much larger range.


Is the problem 100% reproduceable:

This happens every time with this code.


IDE version: 7.11

Compiler: BoostC

Compiler version:

"C:\Program Files\SourceBoost\boostc_pic18.exe" CBSDFileSystem.c -t PIC18F2620 -idx 2 -I ../CBLib -obj Debug -d _DEBUG

BoostC Optimizing C Compiler Version 7.11 (for PIC18 architecture)

Target device: PIC18F2620

OS: Windows 7





"C:\Program Files\SourceBoost\boostc_pic18.exe" CBSDFileSystem.c -t PIC18F2620 -idx 2 -I ../CBLib -obj Debug -d _DEBUG

BoostC Optimizing C Compiler Version 7.11 (for PIC18 architecture)


Building CASM file

Memory Usage Report


RAM available:3968 bytes, used:3647 bytes (92.0%), free:321 bytes (8.0%),

Heap size:321 bytes, Heap max single alloc:127 bytes

ROM available:65536 bytes, used:39368 bytes (60.1%), free:26168 bytes (39.9%)






I'm working on a SD card FAT 12/16/32 file system and ran into a problem where the code running on the PIC and in the simulator misbehave. I tracked it down to what appears to be an assembler bug not flagging an error. Here is a little code segment from my giant case command interpreter case statement:



ORG 0x00008E16

8E16 RemoteMain_00000

8E16 ; { RemoteMain ; function begin

8E16 label744

8E16 EC9CF03C CALL RS232getch_00000




960E 5120 MOVF RemoteMain_00000_1_Resp, W, 1

9610 010C MOVLB 0x0C

9612 6F38 MOVWF RS232putch_00000_arg_ByteVal, 1

9614 EC95F03C CALL RS232putch_00000


9618 D3FE BRA label744


This should have never assembled as the distance from the BRA label744 (address=0x9618) to the destination of label744 at 8E16 is -0x802 or negative 2050. The BRA instruction range is -1023 to +1023. The assembler/linker took the 2's complement of 0x802 and got 0x7fe, tossed bits 10 and 11 and came up with 0x3fe for the branch which is a positive branch instead of a negative branch so the program runs off the end of memory and wraps back to zero and restarts.


Just build the attached project and look at the .lst file produced. I made this in debug mode which is what the project will default to when opened. I simulate with a couple custom plugins but you don't need to simulate to see the problem.




Edited by trossin
Link to post
Share on other sites

I tried a simpler case with just a large while loop and found that the compiler/assembler correctly generated a GOTO. So the bug seems to only be with case statements.


void main()
unsigned long a=0,b=1,c=2;

a = a + b + c;
a = a + b + c;


a = a + b + c;
a = a + b + c;



10C0 5014 MOVF CompTempVar1002, W
10C2 6E04 MOVWF main_1_a+D'3'
10C4 EF12F000 GOTO label1
10C8 ; } main function end

Link to post
Share on other sites

I downloaded version 7.20 and found that my original case still fails.


I did more experiments on version 7.20 and found that the problem only shows up if your code is assembled at a somewhat large address. When label1 is 0x0028, the results are correct. If I moved it out to 0x1964 by adding more code it fails. In this case, the end of case 1 did a positive branch (nearly max) instead of a negative branch back to label 1. I attached a simpler project to reproduce the failure.


I should also mention that this project has some code commented out that crashes the compiler with an access violation.


Here are some snippets from the attached project .lst file showing the bug.


1964 label1
1964 520D MOVF main_1_command, F




2164 6E04 MOVWF main_1_a+D'3'
2166 D3FE BRA label1 // branch is signed number in bits 10:0 (this is a positive branch!).
2168 label4
2168 0E11 MOVLW 0x11
216A 6E01 MOVWF main_1_a
216C 6A02 CLRF main_1_a+D'1'
216E 6A03 CLRF main_1_a+D'2'
2170 6A04 CLRF main_1_a+D'3'
2172 EFB2F00C GOTO label1
2176 ; } main function end






Link to post
Share on other sites

The crash was caused by stack overflow. We will need to restructure compiler code a bit to prevent this from happening.


The wrong jump is on our todo list.




Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...