Hi!

Yes and no, I guess there are two things mixe dup here.

First, U0TXBUF, if defined as a constant, should be assembled directly. It 
isn't, so for some reason it is not interpreted as a predefined constant but as 
a yet unknown symbol.

Unknown sybols are treated as zero values and added to a 'relocation table' 
which is part of the object file. It is the job of a linkter to pick all 
symbols in all object files of a project and put their addresses into the 
'zero' 
placeholders in the other object files, as referenced in the relocation table.
It is sort of a 'hey linker, if you happen to find out where this "U0TXBUF" is, 
pleas put its address at location xxxx in this object file' message.

Depending on the assembler implementation (I don't know the mspgcc assembler 
well) it is possible that any forward reference (a symbol that refers to a 
location later in the source file) can be treated as unknown or 
external reference annd needs a linker to be resolved. (so-called 
one-pass-assembler). Or the assembler fails to determine the final address of a 
symbol because it refers to a location with a yet unknown address (e.g. 
a ocde with its own .org or .segment directive). Since the destination finds 
its final place at linkign time, it's also up to the linker to propagate its 
final address to every location where it is used. The assembler 
generates a relocation table entry and leaves the binary value zero.

As long as you do not have unknown symbols (e.g. if you only have one single 
source file, a contiguous block of code and no libraries), you don't really 
need the linker. There shouldn't be any unresolved external 
symbols.

But apparently there are. The question is: why?
Somehow, U0TXBUF is unknown to the assembler. This might have several reasons: 
Either the preprocessor isn't run, so the token 'U0TXBUF' isn't replaced by its 
defined value, or the include file with the definition 
isn't included at all.

With the .arch directive you tell the assembler which processor you use (and 
therefore which binary values will result from the mnemonics you write). But it 
does not include any definitions.
This are two completely separate things. The processor type must be known 
because different processors might have different optimisations, including 
errata, microcode bugs etc. of wich the assembler needs to take 
care and perhaps create workarounds. It doe snot tello the assembler about 
functional specifics like I/O modules and ports, amount and location of RAM and 
FLASH etc. Just about the microprocessor core itself. The 
programmer needs to take care of this - or use a properly configured linker.
The port definitions, however, are just equations (like the .eq directive) and 
inlcuding the proper file is not necessary for the assembler. It just makes 
things easier for the programmer. So it is NOT done automatically - 
and the file(s) can have any name.

When using a linker, specifying the used processor is necessary to tell the 
linker which processor specific configuration table to use. This includes the 
information, where on the choosen processor the ram starts and 
ends and the flash starts and ends.

In your source file, you jsut tell the assembler to put the following code 
explixitely at 0xe080. So the result is a 64K block of binary data with the 
assembled code at 0xe080.
When using a linker, you'd rather tell the assembler to put the code into an 
arbitrary 'segment' with the name "text". The linker then looks into the 
configuration table and finds out that "text" is from 0xe000 to 0xff80 
and generates a proper binary with all code assigned to the text segment placed 
into this area.
I'm not sure about the '.text' directive just after the '.org'. It could be a 
shortcut for settign the segment, but I must admit that this confuses me a 
little, as this would override the '.org' address and put the code 
somewhere in the text segment, which absolute address is not known. This would 
explain why the reference to the later used 'message' is not immediately 
resolved - it is unknown at which absolute address 
'message' will be after all is placed into the yet unspecified text segment.

So ensure that the include files are really included. I just double-checke the 
inlude files and found that U0TXBUF is equal to U0TXBUF_ when in assembly mode, 
so you can use the labels without underscore.
Also ensure that the assembler is preceded with a precompiler run to resolve 
all these labels (but I guess, mspgcc will do so automatically).
The #include precompiler directive in you code snipped is empty. It does not 
generate an error, so I guess the precompiler is run, but since it has no 
filename appended, it just includes nothing.

my makefiles contain the following line for doing assembly source to object 
files:

msp430-gcc -x assembler-with-cpp -c -mmcu=msp430x1232 -I. f.s -o f.o

next step is linking through gcc

msp430-gcc -mmcu=msp430x1232 f.o -o f.elf

here, instead of just 'f.o', any number of files can be given. They will be all 
put together., all code (except code with a fixed .org instead of a destination 
segment) chained up in the appropriate memory areas, all 
references between these files solved and replaced itn the object data and so 
on.

I automatically create a full disassembler listing of the resulting file with 

msp430-objdump -DS f.elf > f.lst

final step is the conversion of the elf file in a HEX file for flashing:

msp430-objcopy -O ihex f.elf f.hex

you can replace the 'ihex' by 'binary' if you want a binary output file (see 
msp430-objdump --help)

I'm not sure that the above commands are 100% correct as I have them 'manually' 
extracted from my standard makefile (which is a bit mroe complex and uses lots 
of text replacements for path and names and such. 
But it looks right ;)

Also, I'm not an assembly programmer at all (well, I did it once, for the 
C64/6502 processor and later for GEOS on the PC, but this was espire, an 
object-oriented assembler, and everything was different). So all what I 
have written here might differ from the 'final truth' a bit. So everyone is 
inveited to correct me where I missed the point.
But I guess it will give you a good start understanding what you're dealing 
with.


JMGross

----- Ursprüngliche Nachricht -----
Von: david feldman
An: [email protected]
Gesendet am: 13 Aug 2009 00:57:29
Betreff: [Mspgcc-users] Re: Unexpected output from msp430-gcc assembler (simple 
problem?)


Hello JMGross, thank you for the reply.

I now think the problem is that the assembling/linking process is somehow 
incomplete. In the example below, I'm just referring to a symbol which is in 
the same source file:

        .arch msp430x1232
        #include        
        .org    0xE080
        .text
main:   mov     #message, R14
        jmp  main
message: .ascii "hello world"
        .byte 0
        .end

The instruction "mov #message, R14" is getting assembled as "3E 40 00 00" 

In a nutshell, the assembler is rendering "mov #message, R14" as "mov #0, R14".

I suspect this is closer to the root cause of my problem.

My source code is the file "f.s" and it is being compiled with the command 
"msp430-gcc -c f.s -o f.out
", then converted to intel hex using "msp430-objcopy -O ihex f.out f.hex"

The msp430x12x2.h file is located in /usr/msp430/include, where it appeared 
when I first installed msp430-gcc with apt-get (on a Ubuntu 9.04 system.)

There are no error messages from the command line launch of msp430-gcc.

Is there a linking step I am missing? Perhaps there is a symbol table 
containing the address of message: in the above example, or &U0TXBUF in my 
initial example, which is not getting applied to the 
object code?

Thanks again for the patience of those on the reflector!

Dave

>Hi!



Reply via email to