Skip to main content
Engineering LibreTexts

7.4: Library Files

  • Page ID
    76128
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)\(\newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    Normally when writing programs, the entire program is not written in a single file, but instead libraries of functions, objects, and callbacks are created and tied together in a main program. In this textbook only functional abstraction will be considered, and these functions will be gathered together into library files containing multiple similar functions.

    This section will be covered by first creating a file libTypes.s. First an integer number with an implied decimal point will be explained, and a function to print this variable will be created in this file. Second a function, inchesToFeet, will be written in a file named libConversions.s, and will be called from a main program. The third subsection will show how to compile and link the pieces of the program together and create a valid executable. The final section will give a brief comment on the Unix ar, and the difference between “.a” and “.so” objects in Unix will be explained.

    7.4.1 Library file libConversions.s

    To start this section the concept of an implied decimal point integer number is introduced. This type of number is often called a decimal number with a scale that is the number of digits to the right of the decimal point. Programmers use decimal numbers when they have a value that has a fixed scale, for instance money which is normally represented as dollars and cents ($3.33) with a scale value of 2. This is useful as it removes the impreciseness of floating point numbers (which might try to print out $3.3333333), which are generally harder to use and require more computer resources to do equivalent operations. These numbers will be used here to allow greater accuracy for the functions in this section, without incurring the added complexity of presenting floating point instructions.

    To see how this will work, consider the function printScaledInteger, in the file libTypes.s. It takes two parameters, the integer value to print in r0 and the scaling factor as a power of 10 in r1. For example, the function would be called with a price of $40.96 as r0=3795 and r1 = 100. The following is the function as it exists in the file libTypes.s.

    There are a number of features in this file and functions that that reader should be aware of.

    1. The name of the file is libTypes.s. This is in following with the naming conventions that all library files start with the prefix “lib”.
    2. First, there is a preamble at the top of the file. Any file except for a one-use throw-away file should have a preamble to it (period).
    3. The preamble contains the file name. If the file was printed out, there is nothing worse than being unable to find the file again because the name is not known.
    4. The function is documented with what it does, and what the input and output parameters are to the function. The input and output are only registers, and so names in assembly are in no way self-documenting. You have to say what the parameters are, or no one will know.
    5. The function is named in using a “.global” assembly directive. This implies that this function is called from other files and the assembler should make this function available to the linker so it can be resolved at link time. This will be discussed in more detail later when building the program is covered.
    6. The registers r4 and r5 are preserved registers, and so must be saved when the function is called, and restored when the function returns to the Callee. The is in keeping with the ABI register conventions.
    7. The function follows the standard format and pushes the lr to the stack when the function is entered and pops the lr from the stack when the function exits.
    # FileName: libTypes.s 
    # Author: Chuck Kann 
    # Date: 1/14/2021 
    # Purpose: Function for use on types 
    # 
    # Types defined and functions: 
    # printScaledInt 
    # 
    # Changes: 1/14/2021 - Initial release 
    .global printScaledInt 
    
    # Function: printScaledInt 
    # Purpose: to print a scaled integer value 
    # with the decimal point in the 
    # correct place 
    # 
    # Input: r0 - value to print 
    # r1 - scale in 
    # 
    # Output: r0 - pointer to string that contains 
    # the converted value 
    .text 
    PrintScaledInt:
        # push 
        SUB sp, #4 
        STR lr, [sp, #0] 
        STR r4, [sp, #4] 
        STR r5, [sp, #8] 
        MOV r4, r0 
        MOV r5, r1 
        
        # get whole part and save in r7 
        bl __aeabi_idiv // r0/r1, result in r0 
        MOV r6, r0 
        #get decimal part and save in r7 
        MUL r7, r5, r6 
        SUB r7, r4, r7 
        
        # print the whole part 
        LDR r0, = __PSI_format 
        MOV r1, r6 
        bl printf 
        # print the dot 
        LDR r0, = __PSI_dot 
        bl printf 
        # print the decimal part 
        LDR r0, = __PSI_format 
        MOV r1, r7 
        bl printf 
        
        # pop and return 
        LDR lr, [sp, #0] 
        ADD sp, #4 
        MOV pc, lr 
        
    .data 
        __PSI_format: .asciz "%d" 
        __PSI_dot: .asciz "." 
    #end printScaledInt
    

    13 Function to print an implied decimal point integer

    This function will be used in the next section where a program that reads feet and inches converts the value to a decimal value of feet.

    7.4.2 Library file libTypes.s

    The next program that will be looked at will take inches as an integer number in r0 and convert the value to a one decimal place integer representing the number of feet. For example, if 54 inches is passed in, the function will return a value that will be outputted as 1.5 ft.

    Note that to conserve space, the functions here will not be fully commented. That does not mean it is okay to not document source programs, just that it is impractical to do so in this textbook.

    The first program below is in libConversions.s and converts input as feet and inches into a decimal place value of feet.

    .text 
    inches2Ft: 
        SUB sp, sp, #4 
        STR lr, [sp, #0] 
        
        MOV r3, #10 
        MUL r0, r0,r3 
        MOV r1, #12 
        bl __aeabi_idiv 
        #answer is returned in r0 
        
        LDR lr, [sp, #0] 
        ADD sp, sp, #4 
        MOV pc, lr 
        1. #END inches2Ft
    

    14 Function to convert inches to feet

    The following main program prompts for a value in inches, coverts it to feet, and prints it.

        .text 
        .global main 
    
    main: 
    # Save return to os on stack 
        MOV sp, sp, #4 
        STR lr, [sp, #0] 
        
    # Prompt For An Input in inches 
        LDR r0, =prompt1 
        BL printf 
        
    # Read inches 
        LDR r0, =input1
        SUB sp, sp, #4 
        MOV r1, sp 
        BL scanf 
        LDR r0, [sp, #0] 
        ADD sp, sp, #4
        
    # Convert 
        BL inches2Ft 
        MOV r4, r0
        
    # Printing The Message 
        LDR r0, =format1 
        BL printf 
        MOV r0, r4 
        MOV r1, #10 
        BL printScaledInt 
        LDR r0, =newline 
        BL printf
        
    # Return to the OS 
        LDR lr, [sp, #0] 
        ADD sp, sp, #4 
        MOV pc, lr
    
    .data 
        prompt1: .asciz "Enter the length in inches you want in feet: \n" 
        format1: .asciz "\nThe length in feet is " 
        input1: .asciz "%d" 
        newline: .asciz "\n" 
        num1: .word 0
    

    15 Program to call inches2Ft

    7.4.3 Creating the inches2Ft program

    Trying to compile and run the inches2Ft program directly using the command:

        gcc inches2FtMain.s -o inches2Ft
    

    results in the following error messages:

    /usr/bin/ld: /tmp/cc5VoT5g.o: in function `main': 
    (.text+0x28): undefined reference to `inches2Ft' 
    /usr/bin/ld: (.text+0x40): undefined reference to `printScaledInt' 
    collect2: error: ld returned 1 exit status
    

    The name of the command that had this error is the linker (/usr/bin/ld), and the error says that the functions inches2Ft and intScaledInt could not be found. Thinking about this it is obvious that the problem is that these functions are not in the inches2FtMain.s file, but in two library files. These files must be included when linking the file. The following command will do this:

        gcc inches2FtMain.s libTypes.s libConversions.s -o inches2Ft
    

    When library files are changed they are only compiled once to “.o” files, and linking is done with the object files. The following makefile assembles the “.s” files to “.o” files, and then uses gcc to link all of the “.o” files into a program.

    all: inches2Ft 
    
    MYLIBS = libConversions.o libTypes.o 
    CC = gcc 
    
    inches2Ft: inches2FtMain.o $(MYLIBS) 
        $(CC) $@Main.o $(MYLIBS) -g -o $@ 
        ./$@ 
        
    .s.o: 
        $(CC) $(@:.o=.s) -g -c -o $@ 
        
    clean: 
        rm *.o a.out
    

    16 Makefile for inches2Ft program


    This page titled 7.4: Library Files is shared under a CC BY 4.0 license and was authored, remixed, and/or curated by Charles W. Kann III via source content that was edited to the style and standards of the LibreTexts platform; a detailed edit history is available upon request.

    • Was this article helpful?