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.

MSP-EXP432E401Y: Assembly code questions

Part Number: MSP-EXP432E401Y

I'm just getting started using ARM assembly code and I'm having a hard time finding answers to a few simple questions.

1. Is there a single command for loading a 32 bit address into a register?  Right now I'm using the following 4 commands to load 0x4000C018 into register R1 (for example) and it seems like there must be an easier way.

 mov r1, #0x4000 ; r1: 0x00004000 // uart
 lsl r1, #16 ; r1: 0x40000000
add r1, #0xC000 ; r1: 0x4000C000
add r1, #0x18 ; r1: 0x4000C018

2. Is there a way to load the address of a label? For example, I'd like to be able to load the address of the following string of characters into a register:

string: .byte 0x31, 0x32, 0x33, 0x34

3. Some of the documentation I've read says I can create labels with an EQU command;

two: EQU 2

but when I try to create a label this way in CCS it throws an "Illegal mnemonic" error.  Is there a way to create labels in CCS?

4. It would also be great if I could find a list of all the legal ARM assembly commands.  I haven't been able to find one anywhere.

Thank You

  • Hi Brad,

    There isn't much, if any documentation on MSP432 and assembly.  Here is another posting that might provide some additional guidance.

    For help with the assembler, look in the ASM Assembly language Tools guide for MSP432.

    For detailed information about the ARM instruction set, you will need to refer to the ARM documentation available on the web.

  • Thank you for your response, but I was not able to find the information I am looking for (most of the links in the earlier posting are no longer valid).

    The question I'm most interested in getting an answer to is number 2.  If I define a string of characters:

    string:  .byte 0x31, 0x32, 0x33, 0x34

    then try to load the address of that string into a register:

     mov r1, string

    I get an assembly error "Invalid operand".  There must be a way to load the address of "string" into a register, but I can't find how to load it anywhere in the literature I have searched.

    Thank you for anyone who can answer this. 

  • Hi Brad,

    Yes, unfortunately many of the links from the older posts are no longer supported, as the MSP432 is not recommended for new designs.  Let me see if someone from our SW team can help with an answer.

  • Hi Brad,

    Our SW team passed along this link that might be helpful regarding Q1.

  • Hi Brad,

    It's been a few days since I have heard from you so I’m assuming your question has been answered.
    If this isn’t the case, please click the "This did NOT resolve my issue" button and reply to this thread with more information.
    If this thread locks, please click the "Ask a related question" button and in the new thread describe the current status of your issue and any additional details you may have to assist us in helping to solve your issues.

  • Hi Dennis,

    The link you sent was very helpful in answering Q1.  Thank you for that.

    The problem I'm having now is getting an answer to Q2:  If I define a string of characters:

    string:  .byte 0x31, 0x32, 0x33, 0x34

    then try to load the address of that string into a register with:

    mov r1, string

    I get an assembly error, Invalid operand. If I use this command:

    ldr r1, string

    I get the string itself loaded into r1, not its address.  There must be a way to load the address of "string" into a register, but I can't find how to load it anywhere in the literature I have searched.

    Thank you for any help you can provide.  I'm very eager to get the answer to this question.

  • I suspect you can get somewhere with something like “ldr r1,=string”.

    I haven,t written much assembly in the last 20 years, and as I understand it the Cortex has (at least) two assembly languages (ARM and GCC). When I need a reminder I usually write a fragment of C and look at its build listing (usually a .lst file).

  • No luck with "ldr r1,=string".  The assembler threw three errors; bad term in expression, illegal symbol, and unexpected trailing operands.

    That's a good idea to write a fragment of C and look at the build listing, though I can't think of any C code that would have the requirement to load a register with the address of a label.  Any suggestions on a fragment of C that would have that requirement?

    Thank you for responding.

  • printf(“blah blah”) might do it.

    Failing that, maybe char *str=“blah bla”; printf(str);

    I don’t have any materials here, so I can’t experiment.

  • Here are the disassembled commands:

    char *str="blah"
      adr r0, #0x90
      str r0, [r13, #0x1c]
    printf(str);
      ldr r0, [r13, #0x1c]
      bl printf

    So it looks like the C compiler knew where the string is (at pc + 0x90) and it created an assembly command that loaded the address directly into r0, but the assembly commands never used the label themselves.

    It puzzles me why this is turning into such a difficult question. It seems that any assembler would know where any labeled code or string is located and it should have an obvious command that would allow us to load the address of that label into a register.

    BTW, I just used the disassembler to look at the assembly code because I wasn't able to locate the .lst file.

  • It puzzles me why this is turning into such a difficult question. It seems that any assembler would know where any labeled code or string is located and it should have an obvious command that would allow us to load the address of that label into a register.

    The issue is that the Cortex-M Thumb instructions are either 32-bits or 16-bits wide and one instruction can't encode a 32-bit constant. See How to Load Constants in Assembly for Arm Architecture and Branch and Call Sequences Explained for some background information.

    No luck with "ldr r1,=string"

    That is a GNU assembler pseudo-instruction which can store the address of string in a literal pool and generate a PC-relative instruction to load the constant from a literal pool into a register.

    The TI assembler doesn't support that pseudo-instruction.

    Found Compiler/RM42L432: LDR pseudo instruction replacement with a macro for the TI ARM assembler which should allow a replacement for the GNU LDR pseudo-instruction. I haven't attempted to use the macro myself.

  • Chester: Thank you, thank you. The movw command that I found in the links you provided did the trick and now my code is much cleaner.

    I'm still trying to find a way to create labels for single byte values.  Some of the literature says I can use

    two:  equ  2

    to associate the byte 2 to the label two, but when I try this in the CCS assembler I get an error.  Is there another way to create a label for a single byte value in the CCS assembler?