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.

Compiler/MSP430F5335: Need to place assembly code at specific memory location

Part Number: MSP430F5335

Tool/software: TI C/C++ Compiler

How can I place some assembly code at an exact memory location in flash?  I need the code below in exact memory lotion, specifically in 0x9B54

__divu:	.asmfunc stack_usage(RETADDRSZ)
__remu:
	CLR.W	R14		; Initialize the remainder
	MOV.W	R12,R15		; Copy dividend for shifting
	MOV.W	#1,R12		; Walk 1 across for looping, also hold quotient
div_loop:
	RLA.W	R15		; Shift dividend into remainder
	RLC.W	R14		
	CMP.W	R13,R14		; If current remainder > divisor, subtract
	JNC	set_quotient_bit
	SUB.W	R13,R14
set_quotient_bit:	
	RLC.W   R12		; Set quotient bit (in carry),adv loop bit
	JNC	div_loop
	RET
	.endasmfunc

The reason I need it is because I messed up my boot strap loader and it uses this function.  So if I upgrade the firmware the system will fail, unless it has this function in exact location.

  • Have you reviewed the following resources?

    stackoverflow.com/.../defining-location-of-an-array-in-msp430-assembly
    www.ti.com/.../slau131q.pdf
    www.ti.com/.../slaa140.pdf

    Section 2.4.6 of the Assembly User's Guide (SLAU131) covers the creation of subsections.

    Regards,
    Ryan
  • I did review the resources, I am well aware of all of them. I know how to make sections, but it does not guarantee that the routine will be placed at the beginning of the section and it makes a very messy linker directive. In C++ there is

    #pragma LOCATION(hex_address)

    that does not require any linker directive changes. Is there a way to do something similar to assembly routine?
  • To the best of my knowledge there are not any similar routines but I am not extremely familiar with the assembly language.

    Regards,
    Ryan
  • Contents of post deleted, as incorrect attempt to use .set assembly directive

  • Silver Diamond said:
    In C++ there is

    #pragma LOCATION(hex_address)

    that does not require any linker directive changes. Is there a way to do something similar to assembly routine?

    I used the #pragma LOCATION in a C++ source file for a function, and selected the option to save the assembly listing. The assembly listing showed that:

    a) The function was placed in a section named ".TI.bound:<C++_mangled_function_name>".

    b) The compiler generated a .bound assembler directive to tell the linker to place the function at the address specified by the #pragma LOCATION.

    E.g. the following in the C++ source file:

    #pragma LOCATION (0x95e4);
    void test (void)
    {
    
    }

    Showed the following in the assembly listing:

    	.bound	".TI.bound:_Z4testv", 38372, 0
    ;	C:\ti\ccs740\ccsv7\tools\compiler\ti-cgt-msp430_16.9.6.LTS\bin\opt430.exe C:\\Users\\MR_HAL~1\\AppData\\Local\\Temp\\{4DF911C9-C1AE-44EE-A34F-D97BE9EDFC1D} C:\\Users\\MR_HAL~1\\AppData\\Local\\Temp\\{7A9072F9-E7F7-400B-AB7F-871CCFD33940} 
    	.sect	".TI.bound:_Z4testv"
    	.clink
    	.global	_Z4testv

    The MSP430 Assembly Language Tools v17.9.0.STS User's Guide states the the .bound directive is used internally by the C/C++ compiler, and that you shouldn't use the .bound directive in your own assembly language source files.

    On a quick test using TI v16.9.6.LTS when the following was used in a .asm source file the linker did appear to respect the directive and place the __divu and __remu functions at the requested address of 0x9b54 (based upon inspecting the linker map file and output from the MSP430 Hex Utility):

        .sect ".TI.bound:__divu"
    __divu: .asmfunc stack_usage(RETADDRSZ)
    __remu:
        .bound  ".TI.bound:__divu", 0x9B54, 0
        CLR.W   R14     ; Initialize the remainder
        MOV.W   R12,R15     ; Copy dividend for shifting
        MOV.W   #1,R12      ; Walk 1 across for looping, also hold quotient
    div_loop:
        RLA.W   R15     ; Shift dividend into remainder
        RLC.W   R14
        CMP.W   R13,R14     ; If current remainder > divisor, subtract
        JNC set_quotient_bit
        SUB.W   R13,R14
    set_quotient_bit:
        RLC.W   R12     ; Set quotient bit (in carry),adv loop bit
        JNC div_loop
        RET
        .endasmfunc

    However, since the MSP430 Assembly Language Tools v17.9.0.STS User's Guide states that .bound is only for internal C/C++ compiler use you shouldn't rely upon its use.

  • Thank you so much, such a smart approach. Will try to run with it...

**Attention** This is a public forum