Download presentation
Presentation is loading. Please wait.
Published byMichael Simmons Modified over 9 years ago
1
Separate Assembly allows a program to be built from modules rather than a single source file
2
Advantages of separate assembly separate source files provide a nice structure for dividing a project between several team members separate source files allow separate testing (and thus better isolation and detection of bugs) separate source files provide for easy reuse separate source files minimize the work of reassembly and relinking needed whenever a change occurs in only one source file prewritten libraries provide machine extensions (higher-level functions like square root, if not available as a machine instruction)
3
Programming testing Example programs linked from web pages illustrate subroutines exercised by test drivers individual testing of modules like this is often not done (e.g., we are lazy or we foolishly think we will save time by skipping testing) or testing is done poorly (e.g., we neglect important test cases) "write all the code, bolt it all together, and hope for the best"? - bad idea; it is easier to detect errors and debug when we individually test than when we combine previously tested and debugged modules, the remaining errors will probably stem from misunderstandings about the interface specifications (i.e., the number, ordering, and data types of the actual parameters in the subroutine calls)
4
Programming testing bottom-up development: –write and test the lowest-level (leaf) subroutines first, then write the modules or program that uses them –requires extra effort of writing test drivers top-down development: –write the highest-level modules/program first and test the logic; –requires extra effort of writing "stub" routines that are simply place holders for lower-level subroutines that will be developed later; these stubs can return fixed values if necessary and are often useful just to print that the call occurred (and optionally print what parameters were passed)
5
Programming testing Programmers often mix the two approaches –top-down typically offers the ability to quickly and easily prototype a program and obtain feedback from the end user –see this essay by Paul Graham on "Programming Bottom-Up" in which he argues that bottom-up programs are usually smaller and easier to read: http://www.paulgraham.com/progbot.html
6
Linking objects compiler or assembler produces object file (.o) -- using -c flag for armc linker (unfortunately named ld since ln already used as a file system command) yields an executable file (default name is a.out)
7
Linking objects in file p1.s.global main.global x x:.word 55 y:.word 66 main: push {lr} prt_addr: ldr r1, =x ldr r0, =fmt1 bl printf prt_value: ldr r0, =x ldr r1,[r0] ldr r0, =fmt2 bl printf return: pop {pc}.section ".rodata" fmt1:.asciz "the address of x is %p\n" fmt2:.asciz "the value of x is %d\n"
8
Linking objects in file p2.s.global x.section ".data" x:.word 55 y:.word 66 [03:08:42] rlowe@joey7:~/ [84] armc p1.s /tmp/ccSiPZZk.o: In function `return': (.text+0x24): undefined reference to `x' collect2: ld returned 1 exit status
9
Linking objects [03:13:18] rlowe@joey7: [89] armc -c p1.s [03:13:28] rlowe@joey7: [90] nm p1.o nm - prints symbols in object file or 00000000 t $a executable file 00000024 t $dr = read only data (addresses are 00000000 r fmt1 relative to data section) 00000018 r fmt2T = text (addresses are relative to text 00000000 T main section U printf U = undefined 00000004 t prt_addrt = text (lower case type code => 00000010 t prt_value private, upper case type code => 00000020 t return global U x U = undefined
10
Linking objects [03:25:39] rlowe@joey7 [95] armc -c p2.s [03:25:47] rlowe@joey7 [96] nm p2.o 00000000 D x D = data (lower case type code => private 00000004 d y lower case type code => public
11
Linking objects [03:52:49] [107] arm-linux-gnueabi-gcc p1.o p2.o nm a.out // could use ld p1.o p2.o... 00008924 t $a 00008e90 t $a... 00008924 T main.. U printf@@GLIBC_2.4... undefined since 00008928 t prt_addr default is dynamic 00008934 t prt_value linking to shared 00008944 t return object for printf 00069078 D x 0006907c d y [04:06:40] rlowe@joey7:[120]./a.out the address of x is 0x69078 the value of x is 55
12
Linking objects the linker resolves external references between.o (simple object files),.a (libraries/archives), and.so (shared objects) the linker also performs storage management to assign regions within the executable file to each program section; the linker resolves any external references and also performs relocation, that is, it fixes addresses within the program sections relative to each other
13
Linking objects simple object files and libraries/archives are combined using static linking to make a self-contained executable (i.e., all parts needed for execution are contained in the executable); however, for common library routines such as printf, this requires too much disk space for every executable that uses the common routine to have to store its own copy
14
Linking objects shared objects use dynamic linking (at run time) to save disk space (since the program doesn't need to keep a copy of the shared object inside its executable file) and memory space (since many programs can share a single memory-resident copy of the shared object); e.g., using static linking (arm-gnueabi-gcc --static) on p1.s and p2.s resulted in an executable file size of 452016 bytes, which was reduced to 7962 bytes when dynamic linking was used (arm-gnueabi-gcc)
15
Linking objects (dynamic link libraries (DLLs) in Windows systems are similar to shared objects, however, some early Windows systems would link DLL files into a complete executable memory image at load time rather than run time)
16
Linking objects dynamic linking Originally all programs were linked statically ₋ All external references fully resolved ₋ Each program complete Since late 1980's most systems have supported shared libraries and dynamic linking: ₋ For common library packages, only keep a single copy in memory, shared by all processes. ₋ Don't know where library is loaded until runtime; must resolve references dynamically, when program runs.
17
Linking objects dynamic linking One way of implementing dynamic linking: jump table. ₋ Jump table: an array in which each entry is a single machine instruction containing an unconditional branch (jump). ₋ For each function in a shared library used by the program, there is one entry in the jump table that will jump to the beginning of that function. ₋ If one of the files being linked is a shared library, the linker doesn't actually include the shared library code in the final program. Instead it creates a jump table with slots for all of the functions that are used from that library.
18
Linking objects dynamic linking One way of implementing dynamic linking: jump table. ₋ For relocation records referring to functions in the shared library, the linker substitutes the address of the jump table entry: when the function is invoked, the caller will "call" the jump table entry, which redirects the call to the real function. ₋ When the program starts up, the shared library is loaded into memory and the jump table addresses are adjusted to reflect the load location.
19
Linking objects static linking advantages executable is self-contained no run-time overhead dynamic linking advantages reduced disk space for executable only one copy of shared routine needs to be in memory, thus reduced memory space across several currently executing programs will get latest version of shared object
20
Linking example.global main, sub1, y main: push {lr} ldr r0, =x bl sub1 ldr r2, =y ldr r1, [r2] ldr r3, =x ldr r2, [r3] ldr r0, =fmt bl printf mov r0, #0 pop {pc}.section ".data" x:.word 1 y:.word 5.section ".rodata" fmt:.asciz "\nx = %d y = %d\n\n"
21
Linking example /** sub1 **/ sub1: push {lr} add r0,r0, #4 bl sub2 pop {pc} /** sub2 ***/.global sub2,y sub2: push {lr} ldr r1, =y ldr r2, [r1] add r1, r2, #1 str r1,[r0] pop {pc} ~
22
Loading running a program == actual _loading_ into memory and then _branching_ to the entry point address loader usually performs address relocation as words containing absolute addresses are loaded into memory; relocation is required in both the linker and the loader so that the program will run correctly (with the correct addresses)
23
Summary PC-relative offset * caller and subroutine in same source file bound-- * caller and subroutine in different files --bound-- absolute address * definitions and use in same source file boundmay need relocation * definition and use in different files --boundmay need relocation AssemblerLinkerLoading
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.