This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

GCC Toolchain: ASM program won't start

Other Parts Discussed in Thread: MSP430FR6989

Hello,

I have encountered a lot of strange bugs while trying to run a simple assembly program using the TI/Redhat GCC 4.9 toolchain. I have no trouble compiling and running C programs with this toolchain, but at the moment I am interested in writing startup code in assembly for educational purposes. I am able to get the program running if I connect to it in GDB and run the following commands:

monitor reset
set $pc = _start

If I don't use the above two commands, the debugger shows me that the PC is at 0xFFFF or 0x0002. Trying to single-step from these addresses does not work, of course. And If I do start the program correctly in the debugger, I still end up with two other weird issues: Branching to main doesn't work, and using xor.b on an I/O register doesn't work (but the equivalent read-modify-write does work!)

Here's the program:

#include <msp430.h>

# blink.S: Blink the LED on P1.0
.section .resetvec .short _start .section .text _start: mov.w __stack, SP # mov main, PC # Branch to main doesn't work - PC ends up at 0x40b2 main: mov.w #WDTPW | WDTHOLD, &WDTCTL bic.b #BIT0, &PM5CTL0 bis.b #BIT0, &P1DIR bis.b #BIT0, &P1OUT blink: mov.w #25000, r4 loop: dec r4 nop nop jnz loop # This works... mov.b &P1OUT, r5 xor.b #BIT0, r5 mov.b r5, &P1OUT jmp blink # But this doesn't. # xor.b 0x01, &P1OUT

Here is the output of an objdump for the program:

Idx Name          Size      VMA       LMA       File off  Algn
  0 __reset_vector 00000002  0000fffe  0000fffe  000000cc  2**0
                  CONTENTS, READONLY
  1 .rodata       00000004  00004400  00004400  00000094  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  2 .upper.data   00000002  00010000  00004404  00000098  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  3 .text         00000032  00004406  00004406  0000009a  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  4 .MP430.attributes 00000017  00000000  00000000  000000ce  2**0
                  CONTENTS, READONLY

Disassembly of section .text:

00004406 <_start>:
    4406:	11 40 f8 df 	mov	0xdff8,	r1	;PC rel. 0x2400
    440a:	10 40 02 00 	br	0x0002		;PC rel. 0x440e

0000440e <main>:
    440e:	b2 40 80 5a 	mov	#23168,	&0x015c	;#0x5a80
    4412:	5c 01 
    4414:	d2 c3 30 01 	bic.b	#1,	&0x0130	;r3 As==01
    4418:	d2 d3 04 02 	bis.b	#1,	&0x0204	;r3 As==01
    441c:	d2 d3 02 02 	bis.b	#1,	&0x0202	;r3 As==01

00004420 <blink>:
    4420:	34 40 a8 61 	mov	#25000,	r4	;#0x61a8

00004424 <loop>:
    4424:	14 83       	dec	r4		;
    4426:	03 43       	nop			
    4428:	03 43       	nop			
    442a:	fc 23       	jnz	$-6      	;abs 0x4424
    442c:	55 42 02 02 	mov.b	&0x0202,r5	;0x0202
    4430:	55 e3       	xor.b	#1,	r5	;r3 As==01
    4432:	c2 45 02 02 	mov.b	r5,	&0x0202	;
    4436:	f4 3f       	jmp	$-22     	;abs 0x4420

And this is how I am building and flashing my program:

msp430-elf-gcc -mmcu=msp430fr6989 -std=c99 -Wall -Wextra  -g -O0 -c blinky.S -o blinky.o
msp430-elf-gcc  blinky.o -T/../msp430fr6989.ld -nostdlib  -o main.elf
msp430-elf-objcopy -O ihex main.elf main.hex
MSP430Flasher -w main.hex

Any ideas on what could be causing this strange behavior?
Thanks!

  • Moving to Compiler forum for better support.

    Regards,
    JH
  • Make sure the reset vector section has the right address in it:
    msp430-elf-objdump -S -j __reset_vector blink.elf

    You're also copying the *contents* of the __stack variable to SP, not the *address* of __stack. The linker scripts provide __stack as an address, so you should use "mov #__stack,SP"

    That's probably the problem with "mov main,PC" - you're copying the insn at main into pc, not the address of that insn.
  • The particular incantation I use to set vectors using gas is:

            .section .resetvec,"ax",@progbits
            .word   sys_init
    

    I am not sure what all of that does, but it works for me.

    And of course it is "mov #__stack,r1" to initialize the stack pointer.


    The use of labels between branches and jumps isn't consistent which has given me no end of troubles. Even though I know about it, I sometimes forget. While you say "jmp main" you must use "br #main".

  • The ".word sys_init" means that PC will initially point at the sys_init function, instead of the _start function. How that works is up to you :-)
  • I was referring to the "ax",@progbits part. I think I looked it up once but if I did, I have forgotten what it means.
  • Hello DJ,


    Thanks for your reply. I made the changes you suggested, and the jump to main works now. I'll need to be more careful with the different addressing modes in the future.

    The reset vector section appears to have the right address in it:

    Disassembly of section __reset_vector:
    
    0000fffe <__reset_vector>:
        fffe:	06 44       	interrupt service routine at 0x4406

    0x4406 is the address of _start, as expected