Keil Logo

GENERAL: Locating IMPROPER FIXUP Instructions

Information in this article applies to:

  • C166 All Versions
  • C251 All Versions
  • C51 All Versions

SYMPTOMS

After making changes to a program or after adding in-line assembly improper fixup errors are generated by the linker. For example:

*** ERROR L121: IMPROPER FIXUP
    MODULE:  NO_SP.obj (NO_SPEED1)
    SEGMENT: ?PR?MAIN?NO_SPEED1
    OFFSET:  0099H

CAUSE

A fixup error is generated when it is impossible to generate an instruction address that reaches an operand. This is frequently the case with instructions that implement relative jumps or branches. Typically, improper fixups are caused by in-line assembly code that attempts to access an address that is too far away. The error message listed above was generated by a program that included in-line assembly.

You can easily find the assembler instruction that contains an improper fixup using the information provided by the error message. In the case of the error listed above...

  • MODULE: refers to an object file created by the compiler or assembler. You will need the listing file for this module to locate the offending instruction. For C source files, use the CODE directive to include assembler instructions in the listing file. If you used in-line assembly, use the list file created by the assembler. In µVision2, listing file options are available in Project - Options - Listing.
  • SEGMENT: provides the name of the segment where the fixup error exists. The segment name usually refers to a function. You should note, however, that constants may also create improper fixups. In this example, the segment ?PR?MAIN?NO_SPEED1 contains the assembler instructions of the function main which may be found in the C listing file. Search in the ASSEMBLY LISTING OF GENERATED CODE section of the listing file for the segment name. A line similar to RSEG ?PR?main?NO_SPEED1 denotes the beginning of the segment with the fixup error.
  • OFFSET: refers to an instruction offset within the segment. The listing file includes the offset along with the instruction for each segment so you should be able to use this information to locate the instruction with the fixup error. In this example the listing file near offset 0099H appears as follows:

    0096 782D            609             MOV     R0,#10       ; delay factor 10
    0098 D800     F      610             DJNZ    R0,0         ; count down delay
    009A 7E08            611             MOV     R6,#8
    

    The problem is with the DJNZ instruction at offset 0099H. In this case, the DJNZ is attempting to jump to address 0000h but fails because relative jumps can only reach locations that are within a +/- 128 byte range.

    Upon examination of the code at the point of the fixup error, it is apparent that a jump to 0000h was not intended. Instead a simple delay loop should be generated and the DJNZ instruction should jump to itself. This can be accomplished by changing the DJNZ instruction in the in-line assembly to DJNZ R0,$. After making this change, the assembler correctly inserts a jump to the DJNZ instruction and the linker no longer generates the fixup error.

SEE ALSO


Last Reviewed: Thursday, February 25, 2021


Did this article provide the answer you needed?
 
Yes
No
Not Sure
 
  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.