14. Appendix¶
14.1. Common x86 Instructions¶
14.1.1. Reading the Tables¶
The tables of instructions presented in this appendix include:
The instruction code
The operands used
The flags used
A brief description of what the instruction does
In the operands section, it will list the type of operands it takes. If it takes more than one operand, each operand will be separated by a comma. Each operand will have a list of codes which tell whether the operand can be an immediate-mode value (I), a register (R), or a memory address (M). For example, the movl instruction is listed as I/R/M, R/M . This means that the first operand can be any kind of value, while the second operand must be a register or memory location. Note, however, that in x86 assembly language you cannot have more than one operand be a memory location.
In the flags section, it lists the flags in the %eflags register affected by the instruction. The following flags are mentioned:
O
Overflow flag. This is set to true if the destination operand was not large enough to hold the result of the instruction.
S
Sign flag. This is set to the sign of the last result.
Z
Zero flag. This flag is set to true if the result of the instruction is zero.
- A
Auxiliary carry flag. This flag is set for carries and borrows between the third and fourth bit. It is not often used.
P
Parity flag. This flag is set to true if the low byte of the last result had an even number of 1 bits.
C
Carry flag. Used in arithmetic to say whether or not the result should be carried over to an additional byte. If the carry flag is set, that usually means that the destination register could not hold the full result. It is up to the programmer to decide on what action to take (i.e. - propogate the result to another byte, signal an error, or ignore it entirely).
Other flags exist, but they are much less important.
14.1.2. Data Transfer Instructions¶
These instructions perform little, if any computation. Instead they are mostly used for moving data from one place to another.
movl (I/R/M \(\rightarrow\) I/R/M, O/S/Z/A/C)
This copies a word of data from one location to another. movl %eax, %ebx
copies the contents of %eax
to %ebx
.
movb (I/R/M \(\rightarrow\) I/R/M, O/S/Z/A/C)
Same as movl
, but operates on individual bytes.
leal (M \(\rightarrow\) I/R/M, O/S/Z/A/C)
This takes a memory location given in the standard format, and, instead of
loading the contents of the memory location, loads the computed address. For
example, leal 5(%ebp, %ecx, 1), %eax
loads the address computed by 5 + %ebp + 1*%ecx
and stores that in %eax
.
popl (R/M, O/S/Z/A/C)
Pops the top of the stack into the given location. This is equivalent to
performing movl (%esp), R/M
followed by addl $4, %esp
. popfl
is a variant which pops the top of the stack into the %eflags
register.
pushl (I/R/M, O/S/Z/A/C)
Pushes the given value onto the stack. This is the equivalent to performing
subl $4, %esp
followed by movl I/R/M, (%esp)
. pushfl
is a variant
which pushes the current contents of the %eflags register onto the top of the
stack.
xchgl (R/M \(\rightarrow\) R/M, O/S/Z/A/C)
Exchange the values of the given operands.
14.1.3. Integer Instructions¶
adcl (I/R/M \(\rightarrow\) R/M, O/S/Z/A/P/C)
Add with carry. Adds the carry bit and the first operand to the second, and, if there is an overflow, sets overflow and carry to true. This is usually used for operations larger than a machine word. The addition on the least-significant word would take place using addl , while additions to the other words would used the adcl instruction to take the carry from the previous add into account. For the usual case, this is not used, and addl is used instead.
addl (I/R/M \(\rightarrow\) R/M, O/S/Z/A/P/C)
Addition. Adds the first operand to the second, storing the result in the second. If the result is larger than the destination register, the overflow and carry bits are set to true. This instruction operates on both signed and unsigned integers.
cdq (O/S/Z/A/P/C)
Converts the %eax
word into the double-word consisting of %edx : %eax
with sign extension. The q signifies that it is a quad-word. It’s actually a
double-word, but it’s called a quad-word because of the terminology used in the
16-bit days. This is usually used before issuing an idivl instruction.
cmpl (I/R/M \(\rightarrow\) R/M, O/S/Z/A/P/C)
Compares two integers. It does this by subtracting the first operand from the second. It discards the results, but sets the flags accordingly. Usually used before a conditional jump.
decl (R/M, O/S/Z/A/P)
Decrements the register or memory location. Use decb to decrement a byte instead of a word.
divl (R/M, O/S/Z/A/P)
Performs unsigned division. Divides the contents of the double-word contained
in the combined %edx : %eax
registers by the value in the register or
memory location specified. The %eax
register contains the resulting
quotient, and the %edx
register contains the resulting remainder. If the
quotient is too large to fit in %eax
, it triggers a type 0 interrupt.
idivl (R/M, O/S/Z/A/P)
Performs signed division. Operates just like divl above.
imull (R/M/I \(\rightarrow\) R, O/S/Z/A/P/C)
Performs signed multiplication and stores the result in the second operand. If
the second operand is left out, it is assumed to be %eax
, and the
full result is stored in the double-word %edx : %eax
.
incl (R/M, O/S/Z/A/P)
Increments the given register or memory location. Use incb to increment a byte instead of a word.
mull (R/M/I \(\rightarrow\) R, O/S/Z/A/P/C)
Perform unsigned multiplication. Same rules as apply to imull.
negl (R/M, O/S/Z/A/P/C)
Negates (gives the two’s complement inversion of) the given register or memory location.
sbbl (I/R/M \(\rightarrow\) R/M, O/S/Z/A/P/C)
Subtract with borrowing. This is used in the same way that adc is, except for subtraction. Normally only subl is used.
subl (I/R/M \(\rightarrow\) R/M, O/S/Z/A/P/C)
Subtract the two operands. This subtracts the first operand from the second, and stores the result in the second operand. This instruction can be used on both signed and unsigned numbers.
14.1.4. Logic Instructions¶
andl (I/R/M \(\rightarrow\) R/M, O/S/Z/P/C)
Performs a logical and of the contents of the two operands, and stores the result in the second operand. Sets the overflow and carry flags to false.
notl (R/M)
Performs a logical not on each bit in the operand. Also known as a one’s complement.
orl (I/R/M \(\rightarrow\) R/M, O/S/Z/A/P/C)
Performs a logical or between the two operands, and stores the result in the second operand. Sets the overflow and carry flags to false.
rcll (I/%cl
\(\rightarrow\) R/M, O/C)
Rotates the given location’s bits to the left the number of times in the first
operand, which is either an immediate-mode value or the register %cl
. The
carry flag is included in the rotation, making it use 33 bits instead of 32.
Also sets the overflow flag.
rcrl (I/%cl
\(\rightarrow\) R/M, O/C)
Same as above, but rotates right.
roll (I/%cl
\(\rightarrow\) R/M, O/C)
Rotate bits to the left. It sets the overflow and carry flags, but does not
count the carry flag as part of the rotation. The number of bits to roll is
either specified in immediate mode or is contained in the %cl
register.
rorl (I/%cl
\(\rightarrow\) R/M, O/C)
Same as above, but rotates right.
sall (I/%cl
\(\rightarrow\) R/M, C)
Arithmetic shift left. The sign bit is shifted out to the carry flag, and a
zero bit is placed in the least significant bit. Other bits are simply shifted
to the left. This is the same as the regular shift left. The number of bits to
shift is either specified in immediate mode or is contained in the %cl
register.
sarl (I/%cl
\(\rightarrow\) R/M, C)
Arithmetic shift right. The least significant bit is shifted out to the carry
flag. The sign bit is shifted in, and kept as the sign bit. Other bits are
simply shifted to the right. The number of bits to shift is either specified in
immediate mode or is contained in the %cl
register.
shll (I/%cl
\(\rightarrow\) R/M, C)
Logical shift left. This shifts all bits to the left (sign bit is not treated
specially). The leftmost bit is pushed to the carry flag. The number of bits to
shift is either specified in immediate mode or is contained in the %cl
register.
shrl (I/%cl
\(\rightarrow\) R/M, C)
Logical shift right. This shifts all bits in the register to the right (sign bit is not treated specially). The rightmost bit is pushed to the carry flag. The number of bits to shift is either specified in immediate mode or is contained in the %cl register.
testl (I/R/M \(\rightarrow\) R/M, O/S/Z/A/P/C)
Does a logical and of both operands and discards the results, but sets the flags accordingly.
xorl (I/R/M \(\rightarrow\) R/M, O/S/Z/A/P/C)
Does an exclusive or on the two operands, and stores the result in the second operand. Sets the overflow and carry flags to false.
14.1.5. Flow Control Instructions¶
These instructions may alter the flow of the program.
call (destination address, O/S/Z/A/C)
This pushes what would be the next value for %eip
onto the stack, and jumps
to the destination address. Used for function calls. Alternatively, the
destination address can be an asterisk followed by a register for an indirect
function call. For example, call *%eax
will call the function at the
address in %eax
.
int (I, O/S/Z/A/C)
Causes an interrupt of the given number. This is usually used for system calls and other kernel interfaces.
Jcc (destination address, O/S/Z/A/C)
Conditional branch. cc is the condition code. Jumps to the given address if the condition code is true (set from the previous instruction, probably a comparison). Otherwise, goes to the next instruction. The condition codes are:
[n]a[e] - above (unsigned greater than). An n can be added for “not” and an e can be added for “or equal to”
[n]b[e] - below (unsigned less than)
[n]e - equal to
[n]z - zero
[n]g[e] - greater than (signed comparison)
[n]l[e] - less than (signed comparison)
[n]c - carry flag set
[n]o - overflow flag set
[p]p - parity flag set
[n]s - sign flag set
ecxz -
%ecx
is zero
jmp (destination address, O/S/Z/A/C)
An unconditional jump. This simply sets %eip
to the destination address.
Alternatively, the destination address can be an asterisk followed by a
register for an indirect jump. For example, jmp *%eax
will jump to the
address in %eax
.
ret (O/S/Z/A/C)
Pops a value off of the stack and then sets %eip to that value. Used to return from function calls.
14.1.6. Assembler Directives¶
These are instructions to the assembler and linker, instead of instructions to the processor. These are used to help the assembler put your code together properly, and make it easier to use.
.ascii
Takes the given quoted string and converts it into byte data.
.byte
Takes a comma-separated list of values and inserts them right there in the program as data.
.endr
Ends a repeating section defined with .rept.
.equ
Sets the given label equivalent to the given value. The value can be a number, a character, or an constant expression that evaluates to a a number or character. From that point on, use of the label will be substituted for the given value.
.globl
Sets the given label as global, meaning that it can be used from separately-compiled object files.
.include
Includes the given file just as if it were typed in right there.
.lcomm
This is used in the .bss section to specify storage that should be allocated when the program is executed. Defines the symbol with the address where the storage will be located, and makes sure that it is the given number of bytes long.
.long
Takes a sequence of numbers separated by commas, and inserts those numbers as 4-byte words right where they are in the program.
.rept
Repeats everything between this directive and the .endr directives the number of times specified.
.section
Switches the section that is being worked on. Common sections include .text (for code), .data (for data embedded in the program itself), and .bss (for uninitialized global data).
.type
Tells the linker that the given symbol is a function.
14.1.7. Differences in Other Syntaxes and Terminology¶
The syntax for assembly language used in this book is known at the AT&T syntax. It is the one supported by the GNU tool chain that comes standard with every Linux distribution. However, the official syntax for x86 assembly language (known as the Intel® syntax) is different. It is the same assembly language for the same platform, but it looks different. Some of the differences include:
In Intel syntax, the operands of instructions are often reversed. The destination operand is listed before the source operand.
In Intel syntax, registers are not prefixed with the percent sign (%).
In Intel syntax, a dollar-sign ($) is not required to do immediate-mode addressing. Instead, non-immediate addressing is accomplished by surrounding the address with brackets ([]).
In Intel syntax, the instruction name does not include the size of data being moved. If that is ambiguous, it is explicitly stated as BYTE, WORD, or DWORD immediately after the instruction name.
The way that memory addresses are represented in Intel assembly language is much different (shown below).
Because the x86 processor line originally started out as a 16-bit processor, most literature about x86 processors refer to words as 16-bit values, and call 32-bit values double words. However, we use the term “word” to refer to the standard register size on a processor, which is 32 bits on an x86 processor. The syntax also keeps this naming convention - DWORD stands for “double word” in Intel syntax and is used for standard-sized registers, which we would call simply a “word”.
Intel assembly language has the ability to address memory as a segment/offset pair. We do not mention this because Linux does not support segmented memory, and is therefore irrelevant to normal Linux programming.
Other differences exist, but they are small in comparison. To show some of the differences, consider the following instruction:
movl %eax, 8(%ebx,%edi,4)
In Intel syntax, this would be written as:
mov [8 + %ebx + 1 * edi], eax
The memory reference is a bit easier to read than it’s AT&T counterpart because it spells out exactly how the address will be computed. However, but the order of operands in Intel syntax can be confusing.
14.1.8. Where to Go for More Information¶
Intel has a set of comprehensive guides to their processors. These are available at http://www.intel.com/design/pentium/manuals/ Note that all of these use the Intel syntax, not the AT&T syntax. The most important ones are their IA-32 Intel Architecture Software Developer’s Manual in its three volumes:
Volume 1: System Programming Guide
http://developer.intel.com/design/pentium4/manuals/245470.htm
Volume 2: Instruction Set Reference
http://developer.intel.com/design/pentium4/manuals/245471.htm
Volume 3: System Programming Guide
http://developer.intel.com/design/pentium4/manuals/245472.htm
In addition, you can find a lot of information in the manual for the GNU assembler, available online at https://sourceware.org/binutils/docs/as. Similarly, the manual for the GNU linker is available online at https://sourceware.org/binutils/docs/ld.
14.2. Important System Calls¶
These are some of the more important system calls to use when dealing with Linux. For most cases, however, it is best to use library functions rather than direct system calls, because the system calls were designed to be minimalistic while the library functions were designed to be easy to program with. For information about the Linux C library, see the manual at http://www.gnu.org/software/libc/manual.
Remember that %eax holds the system call numbers, and that the return values and error codes are also stored in %eax .
|
Name |
|
|
|
Notes |
---|---|---|---|---|---|
1 |
exit |
return value (int) |
Exits the program |
||
3 |
read |
file descriptor |
buffer start |
buffer size (int) |
Reads into the given buffer |
4 |
write |
file descriptor |
buffer start |
buffer size (int) |
Writes the buffer to the file descriptor |
5 |
open |
null-terminated filename |
option list |
permission mode |
Opens the given file. Returns the file descriptor or an error number. |
6 |
close |
file descriptor |
Closes the given file descriptor |
||
12 |
chdir |
null-terminated directory name |
Changes the current directory of your program. |
||
19 |
lseek |
file descriptor |
offset |
mode |
Repositions where you are in the given file. The mode (called the “whence”) should be 0 for absolute positioning, and 1 for relative positioning. |
20 |
getpid |
Returns the process id of the current process. |
|||
39 |
mkdir |
null-terminated directory name |
permission mode |
Creates the given directory. Assumes all directories leading up to it already exist. |
|
40 |
rmdir |
null-terminated directory name |
Removes the given directory. |
||
41 |
dup |
file descriptor |
Returns a new file descriptor that works just like the existing file descriptor. |
||
42 |
pipe |
pipe array |
Creates two file descriptors, where writing on one produces data to read on the other and vice-versa. %ebx is a pointer to two words of storage to hold the file descriptors. |
||
45 |
brk |
new system break |
Sets the system break (i.e. - the end of the data section). If the system break is 0, it simply returns the current system break. |
||
54 |
ioctl |
file descriptor |
request |
arguments |
This is used to set parameters on device files. It’s actual usage varies based on the type of file or device your descriptor references. |
A more complete listing of system calls, along with additional information is available at https://filippo.io/linux-syscall-table.
You can also get more information about a system call by typing in man 2
SYSCALLNAME which will return you the information about the system call from
section 2 of the UNIX manual. However, this refers to the usage of the system
call from the C programming language, and may or may not be directly helpful.
A list of all system calls is displayed with man 2 syscalls
.
For information on how system calls are implemented on Linux, see the Linux Kernel 2.4 Internals section on how system calls are implemented at http://www.faqs.org/docs/kernel_2_4/lki-2.html#ss2.11 (XXX link is outdated).
14.3. Table of ASCII Codes¶
To use this table, simply find the character or escape that you want the code for, and add the number on the left and the top.
ASCII(7) Linux Programmer's Manual ASCII(7)
NAME
ascii - ASCII character set encoded in octal, decimal, and hexadecimal
DESCRIPTION
ASCII is the American Standard Code for Information Interchange. It is
a 7-bit code. Many 8-bit codes (e.g., ISO 8859-1) contain ASCII as
their lower half. The international counterpart of ASCII is known as
ISO 646-IRV.
The following table contains the 128 ASCII characters.
C program '\X' escapes are noted.
Oct Dec Hex Char Oct Dec Hex Char
────────────────────────────────────────────────────────────────────────
000 0 00 NUL '\0' (null character) 100 64 40 @
001 1 01 SOH (start of heading) 101 65 41 A
002 2 02 STX (start of text) 102 66 42 B
003 3 03 ETX (end of text) 103 67 43 C
004 4 04 EOT (end of transmission) 104 68 44 D
005 5 05 ENQ (enquiry) 105 69 45 E
006 6 06 ACK (acknowledge) 106 70 46 F
007 7 07 BEL '\a' (bell) 107 71 47 G
010 8 08 BS '\b' (backspace) 110 72 48 H
011 9 09 HT '\t' (horizontal tab) 111 73 49 I
012 10 0A LF '\n' (new line) 112 74 4A J
013 11 0B VT '\v' (vertical tab) 113 75 4B K
014 12 0C FF '\f' (form feed) 114 76 4C L
015 13 0D CR '\r' (carriage ret) 115 77 4D M
016 14 0E SO (shift out) 116 78 4E N
017 15 0F SI (shift in) 117 79 4F O
020 16 10 DLE (data link escape) 120 80 50 P
021 17 11 DC1 (device control 1) 121 81 51 Q
022 18 12 DC2 (device control 2) 122 82 52 R
023 19 13 DC3 (device control 3) 123 83 53 S
024 20 14 DC4 (device control 4) 124 84 54 T
025 21 15 NAK (negative ack.) 125 85 55 U
026 22 16 SYN (synchronous idle) 126 86 56 V
027 23 17 ETB (end of trans. blk) 127 87 57 W
030 24 18 CAN (cancel) 130 88 58 X
031 25 19 EM (end of medium) 131 89 59 Y
032 26 1A SUB (substitute) 132 90 5A Z
033 27 1B ESC (escape) 133 91 5B [
034 28 1C FS (file separator) 134 92 5C \ '\\'
035 29 1D GS (group separator) 135 93 5D ]
036 30 1E RS (record separator) 136 94 5E ^
037 31 1F US (unit separator) 137 95 5F _
040 32 20 SPACE 140 96 60 `
041 33 21 ! 141 97 61 a
042 34 22 " 142 98 62 b
043 35 23 # 143 99 63 c
044 36 24 $ 144 100 64 d
045 37 25 % 145 101 65 e
046 38 26 & 146 102 66 f
047 39 27 ' 147 103 67 g
050 40 28 ( 150 104 68 h
051 41 29 ) 151 105 69 i
052 42 2A * 152 106 6A j
053 43 2B + 153 107 6B k
054 44 2C , 154 108 6C l
055 45 2D - 155 109 6D m
056 46 2E . 156 110 6E n
057 47 2F / 157 111 6F o
060 48 30 0 160 112 70 p
061 49 31 1 161 113 71 q
062 50 32 2 162 114 72 r
063 51 33 3 163 115 73 s
064 52 34 4 164 116 74 t
065 53 35 5 165 117 75 u
066 54 36 6 166 118 76 v
067 55 37 7 167 119 77 w
070 56 38 8 170 120 78 x
071 57 39 9 171 121 79 y
072 58 3A : 172 122 7A z
073 59 3B ; 173 123 7B {
074 60 3C < 174 124 7C |
075 61 3D = 175 125 7D }
076 62 3E > 176 126 7E ~
077 63 3F ? 177 127 7F DEL
Tables
For convenience, below are more compact tables in hex and decimal.
2 3 4 5 6 7 30 40 50 60 70 80 90 100 110 120
------------- ---------------------------------
0: 0 @ P ` p 0: ( 2 < F P Z d n x
1: ! 1 A Q a q 1: ) 3 = G Q [ e o y
2: " 2 B R b r 2: * 4 > H R \ f p z
3: # 3 C S c s 3: ! + 5 ? I S ] g q {
4: $ 4 D T d t 4: " , 6 @ J T ^ h r |
5: % 5 E U e u 5: # - 7 A K U _ i s }
6: & 6 F V f v 6: $ . 8 B L V ` j t ~
7: ' 7 G W g w 7: % / 9 C M W a k u DEL
8: ( 8 H X h x 8: & 0 : D N X b l v
9: ) 9 I Y i y 9: ' 1 ; E O Y c m w
A: * : J Z j z
B: + ; K [ k {
C: , < L \ l |
D: - = M ] m }
E: . > N ^ n ~
F: / ? O _ o DEL
...
Linux 2014-10-02 ASCII(7)
ASCII is actually being phased out in favor of an international standard known as Unicode, which allows you to display any character from any known writing system in the world. As you may have noticed, ASCII only has support for English characters. Unicode is much more complicated, however, because it requires more than one byte to encode a single character. There are several different methods for encoding Unicode characters. The most common is UTF-8 and UTF-32. UTF-8 is somewhat backwards-compatible with ASCII (it is stored the same for English characters, but expands into multiple byte for international characters). UTF-32 simply requires four bytes for each character rather than one. Windows® uses UTF-16, which is a variable-length encoding which requires at least 2 bytes per character, so it is not backwards-compatible with ASCII.
A good tutorial on internationalization issues, fonts, and Unicode is available in a great Article by Joe Spolsky, called “The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)”, available online at http://www.joelonsoftware.com/articles/Unicode.html
14.4. C Idioms in Assembly Language¶
This appendix is for C programmers learning assembly language. It is meant to give a general idea about how C constructs can be implemented in assembly language.
If Statement
In C, an if statement consists of three parts - the condition, the true branch, and the false branch. However, since assembly language is not a block structured language, you have to work a little to implement the block-like nature of C. For example, look at the following C code:
if (a == b)
{
/* True Branch Code Here */
}
else
{
/* False Branch Code Here */
}
/* At This Point, Reconverge */
In assembly language, this can be rendered as:
# Move a and b into registers for comparison
movl a, %eax
movl b, %ebx
# Compare
cmpl %eax, %ebx
# If True, go to true branch
je true_branch
false_branch: # This label is unnecessary,
# only here for documentation
# False Branch Code Here
# Jump to recovergence point
jmp reconverge
true_branch:
# True Branch Code Here
reconverge:
# Both branches recoverge to this point
As you can see, since assembly language is linear, the blocks have to jump around each other. Recovergence is handled by the programmer, not the system.
A case statement is written just like a sequence of if statements.
Function Call
A function call in assembly language simply requires pushing the arguments to the function onto the stack in reverse order, and issuing a call instruction. After calling, the arguments are then popped back off of the stack. For example, consider the C code:
printf("The number is %d", 88);
In assembly language, this would be rendered as:
.section .data
text_string:
.ascii "The number is %d\0"
.section .text
pushl $88
pushl $text_string
call printf
popl %eax
popl %eax #%eax is just a dummy variable,
#nothing is actually being done
#with the value. You can also
#directly re-adjust %esp to the
#proper location.
Variables and Assignment
Global and static variables are declared using .data or .bss entries. Local variables are declared by reserving space on the stack at the beginning of the function. This space is given back at the end of the function.
Interestingly, global variables are accessed differently than local variables in assembly language. Global variables are accessed using direct addressing, while local variables are accessed using base pointer addressing. For example, consider the following C code:
int my_global_var;
int foo()
{
int my_local_var;
my_local_var = 1;
my_global_var = 2;
return 0;
}
This would be rendered in assembly language as:
.section .data
.lcomm my_global_var, 4
.type foo, @function
foo:
pushl %ebp #Save old base pointer
movl %esp, $ebp #make stack pointer base pointer
subl $4, %esp #Make room for my_local_var
.equ my_local_var, -4 #Can now use my_local_var to
#find the local variable
movl $1, my_local_var(%ebp)
movl $2, my_global_var
movl %ebp, %esp #Clean up function and return
popl %ebp
ret
What may not be obvious is that accessing the global variable takes fewer machine cycles than accessing the global variable. However, that may not matter because the stack is more likely to be in physical memory (instead of swap) than the global variable is.
Also note that in the C programming language, after the compiler loads a value into a register, that value will likely stay in that register until that register is needed for something else. It may also move registers. For example, if you have a variable foo , it may start on the stack, but the compiler will eventually move it into registers for processing. If there aren’t many variables in use, the value may simply stay in the register until it is needed again. Otherwise, when that register is needed for something else, the value, if it’s changed, is copied back to its corresponding memory location. In C, you can use the keyword volatile to make sure all modifications and references to the variable are done to the memory location itself, rather than a register copy of it, in case other processes, threads, or hardware may be modifying the value while your function is running.
Loops
Loops work a lot like if statements in assembly language - the blocks are formed by jumping around. In C, a while loop consists of a loop body, and a test to determine whether or not it is time to exit the loop. A for loop is exactly the same, with optional initialization and counter-increment sections. These can simply be moved around to make a while loop.
In C, a while loop looks like this:
while(a < b)
{
/* Do stuff here */
}
/* Finished Looping */
This can be rendered in assembly language like this:
The x86 assembly language has some direct support for looping as well. The
%exc
register can be used as a counter that ends with zero. The loop
instruction will decrement %ecx
and jump to a specified address unless
%ecx
is zero. For example, if you wanted to execute a statement 100 times,
you would do this in C:
for (i=0; i < 100; i++)
{
/* Do process here */
}
In assembly language it would be written like this:
loop_initialize:
movl $100, %ecx
loop_begin:
#
#Do Process Here
#
#Decrement %ecx and loops if not zero
loop loop_begin
rest_of_program:
#Continues on to here
One thing to notice is that the loop
instruction
requires you to be counting backwards to zero. If
you need to count forwards or use another ending number, you should use
the loop form which does not include the loop instruction.
For really tight loops of character string operations, there is also the
rep
instruction, but we will leave learning about that as an exercise to
the reader.
Structs
Structs are simply descriptions of memory blocks. For example, in C you can say:
struct person {
char firstname[40];
char lastname[40];
int age;
};
This doesn’t do anything by itself, except give you ways of intelligently
using 84 bytes of data. You can do basically the same thing using
.equ
directives in assembly language. Like this:
.equ PERSON_SIZE, 84
.equ PERSON_FIRSTNAME_OFFSET, 0
.equ PERSON_LASTNAME_OFFSET, 40
.equ PERSON_AGE_OFFSET, 80
When you declare a variable of this type, all you are doing is reserving 84 bytes of space. So, if you have this in C:
void foo()
{
struct person p;
/* Do stuff here */
}
In assembly language you would have:
foo:
#Standard header beginning
pushl %ebp
movl %esp, %ebp
#Reserve our local variable
subl $PERSON_SIZE, %esp
#This is the variable's offset from %ebp
.equ P_VAR, 0 - PERSON_SIZE
#Do Stuff Here
#Standard function ending
movl %ebp, %esp
popl %ebp
ret
To access structure members, you just have to use base pointer addressingy with the offsets defined above. For example, in C you could set the person’s age like this:
p.age = 30;
In assembly language it would look like this:
movl $30, P_VAR + PERSON_AGE_OFFSET(%ebp)
Pointers
Pointers are very easy. Remember, pointers are simply the address that a value resides at. Let’s start by taking a look at global variables. For example:
int global_data = 30;
In assembly language, this would be:
.section .data
global_data:
.long 30
Taking the address of this data in C:
a = &global_data;
Taking the address of this data in assembly language:
movl $global_data, %eax
You see, with assembly language, you are almost always accessing memory through pointers. That’s what direct addressing is. To get the pointer itself, you just have to go with immediate mode addressing.
Local variables are a little more difficult, but not much. Here is how you take the address of a local variable in C:
void foo()
{
int a;
int *b;
a = 30;
b = &a;
*b = 44;
}
The same code in assembly language:
foo:
#Standard opening
pushl %ebp
movl %esp, %ebp
#Reserve two words of memory
subl $8, $esp
.equ A_VAR, -4
.equ B_VAR, -8
#a = 30
movl $30, A_VAR(%ebp)
#b = &a
movl $A_VAR, B_VAR(%ebp)
addl %ebp, B_VAR(%ebp)
#*b = 30
movl B_VAR(%ebp), %eax
movl $30, (%eax)
#Standard closing
movl %ebp, %esp
popl %ebp
ret
As you can see, to take the address of a local variable, the address has to be
computed the same way the computer computes the addresses in base pointer
addressing. There is an easier way - the processor provides the instruction
leal
, which stands for “load effective address”. This lets the computer
compute the address, and then load it wherever you want. So, we could just
say:
#b = &a
leal A_VAR(%ebp), %eax
movl %eax, B_VAR(%ebp)
It’s the same number of lines, but a little cleaner. Then, to use this value, you simply have to move it to a general-purpose register and use indirect addressing, as shown in the example above.
Getting GCC to Help
One of the nice things about GCC is its ability to spit out assembly language code. To convert a C language file to assembly, you can simply do:
gcc -S file.c
The output will be in file.s
. It’s not the most readable output - most of
the variable names have been removed and replaced either with numeric stack
locations or references to automatically-generated labels. To start with, you
probably want to turn off optimizations with -O0
so that the assembly
language output will follow your source code better.
Something else you might notice is that GCC reserves more stack space
for local variables than we do, and then AND’s %esp
1.
This is to increase memory and cache efficiency by double-word aligning
variables.
Finally, at the end of functions, we usually do the following instructions
to clean up the stack before issuing a ret
instruction:
movl %ebp, %esp
popl %ebp
However, GCC output will usually just include the instruction leave
. This
instruction is simply the combination of the above two instructions. We do not
use leave
in this text because we want to be clear about exactly what is
happening at the processor level.
I encourage you to take a C program you have written and compile it to assembly language and trace the logic. Then, add in optimizations and try again. See how the compiler chose to rearrange your program to be more optimized, and try to figure out why it chose the arrangement and instructions it did.
14.5. Using the GDB Debugger¶
By the time you read this appendix, you will likely have written at least one program with an error in it. In assembly language, even minor errors usually have results such as the whole program crashing with a segmentation fault error. In most programming languages, you can simply print out the values in your variables as you go along, and use that output to find out where you went wrong. In assembly language, calling output functions is not so easy. Therefore, to aid in determining the source of errors, you must use a source debugger.
A debugger is a program that helps you find bugs by stepping through the program one step at a time, letting you examine memory and register contents along the way. A source debugger is a debugger that allows you to tie the debugging operation directly to the source code of a program. This means that the debugger allows you to look at the source code as you typed it in - complete with symbols, labels, and comments.
The debugger we will be looking at is GDB - the GNU Debugger. This application is present on almost all GNU/Linux distributions. It can debug programs in multiple programming languages, including assembly language.
14.5.1. An Example Debugging Session¶
The best way to explain how a debugger works is by using it. The program
we will be using the debugger on is the maximum
program used in <xref linkend=”firstprogs” />. Let’s say that you entered
the program perfectly, except that you left out the line:
incl %edi
When you run the program, it just goes in an infinite loop - it never exits.
To determine the cause, you need to run the program under GDB. However, to do
this, you need to have the assembler include debugging information in the
executable. All you need to do to enable this is to add the
--gstabs
option to the as
command. So,
you would assemble it like this:
as --gstabs maximum.s -o maximum.o
Linking would be the same as normal. “stabs” is the debugging format used
by GDB. Now, to run the program under the debugger, you would type in
gdb ./maximum
. Be sure that the source files are in
the current directory. The output should look similar to this:
GNU gdb Red Hat Linux (5.2.1-4)
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public
License, and you are welcome to change it and/or
distribute copies of it under certain conditions. Type
"show copying" to see the conditions. There is
absolutely no warranty for GDB. Type "show warranty"
for details.
This GDB was configured as "i386-redhat-linux"...
(gdb)
Depending on which version of GDB you are running, this output may vary
slightly. At this point, the program is loaded, but is not running yet. The
debugger is waiting your command. To run your program, just type in run
.
This will not return, because the program is running in an infinite loop. To
stop the program, hit control-c. The screen will then say this:
Starting program: /home/johnnyb/maximum
Program received signal SIGINT, Interrupt.
start_loop () at maximum.s:34
34 movl data_items(,%edi,4), %eax
Current language: auto; currently asm
(gdb)
This tells you that the program was interrupted by the SIGINT signal (from your
control-c), and was within the section labelled start_loop
,
and was executing on line 34 when it stopped. It gives you the code that it is
about to execute. Depending on exactly when you hit control-c, it may have
stopped on a different line or a different instruction than the example.
One of the best ways to find bugs in a program is to follow the flow of the
program to see where it is branching incorrectly. To follow the flow of this
program, keep on entering stepi
(for “step instruction”), which will cause
the computer to execute one instruction at a time. If you do this several
times, your output will look something like this:
(gdb) stepi
35 cmpl %ebx, %eax
(gdb) stepi
36 jle start_loop
(gdb) stepi
32 cmpl $0, %eax
(gdb) stepi
33 je loop_exit
(gdb) stepi
34 movl data_items(,%edi,4), %eax
(gdb) stepi
35 cmpl %ebx, %eax
(gdb) stepi
36 jle start_loop
(gdb) step
32 cmpl $0, %eax
As you can tell, it has looped. In general, this is good, since we wrote it to loop. However, the problem is that it is never stopping. Therefore, to find out what the problem is, let’s look at the point in our code where we should be exiting the loop:
cmpl $0, %eax
je loop_exit
Basically, it is checking to see if %eax
hits zero. If so, it should exit
the loop. There are several things to check here. First of all, you may have
left this piece out altogether. It is not uncommon for a programmer to forget
to include a way to exit a loop. However, this is not the case here. Second,
you should make sure that loop_exit
actually is outside the
loop. If we put the label in the wrong place, strange things would happen.
However, again, this is not the case.
Neither of those potential problems are the culprit. So, the next
option is that perhaps &eax; has the wrong value. There are two ways to
check the contents of register in GDB. The first one is the command
info register
. This will display the contents of
all registers in hexadecimal. However, we are only interested in %eax
at this point. To just display %eax
we can do print/$eax
to print it in hexadecimal, or do print/d $eax
to print
it in decimal. Notice that in GDB, registers are prefixed with dollar
signs rather than percent signs. Your screen should have his on it:
(gdb) print/d $eax
$1 = 3
(gdb)
This means that the result of your first inquiry is 3. Every inquiry you make
will be assigned a number prefixed with a dollar sign. Now, if you look back
into the code, you will find that 3 is the first number in the list of numbers
to search through. If you step through the loop a few more times, you will find
that in every loop iteration %eax
has the number 3. This is not what should
be happening. %eax
should go to the next value in the list in every
iteration.
Okay, now we know that %eax is being loaded with the same value over and over again. Let’s search to see where %eax is being loaded from. The line of code is this:
movl data_items(,%edi,4), %eax
So, step until this line of code is ready to execute. Now, this code depends on
two values - data_items and %edi . data_items is a symbol, and therefore
constant. It’s a good idea to check your source code to make sure the label is
in front of the right data, but in our case it is. Therefore, we need to look
at %edi
. So, we need to print it out. It will look like this:
(gdb) print/d $edi
$2 = 0
(gdb)
This indicates that %edi is set to zero, which is why it keeps on loading the first element of the array. This should cause you to ask yourself two questions - what is the purpose of %edi , and how should its value be changed? To answer the first question, we just need to look in the comments. %edi is holding the current index of data_items . Since our search is a sequential search through the list of numbers in data_items , it would make sense that %edi should be incremented with every loop iteration.
Scanning the code, there is no code which alters %edi at all. Therefore, we should add a line to increment %edi at the beginning of every loop iteration. This happens to be exactly the line we tossed out at the beginning. Assembling, linking, and running the program again will show that it now works correctly.
Hopefully this exercise provided some insight into using GDB to help you find errors in your programs.
Breakpoints and Other GDB Features
The program we entered in the last section had an infinite loop, and could be easily stopped using control-c. Other programs may simply abort or finish with errors. In these cases, control-c doesn’t help, because by the time you press control-c, the program is already finished. To fix this, you need to set breakpoints. A breakpoint is a place in the source code that you have marked to indicate to the debugger that it should stop the program when it hits that point.
To set breakpoints you have to set them up before you run the program. Before
issuing the run command, you can set up breakpoints using the break command.
For example, to break on line 27, issue the command break 27 . Then, when the
program crosses line 27, it will stop running, and print out the current line
and instruction. You can then step through the program from that point and
examine registers and memory. To look at the lines and line numbers of your
program, you can simply use the command l
. This will print out your program
with line numbers a screen at a time.
When dealing with functions, you can also break on the function names. For example, in the factorial program in Chapter 4, we could set a breakpoint for the factorial function by typing in break factorial . This will cause the debugger to break immediately after the function call and the function setup (it skips the pushing of %ebp and the copying of %esp ).
When stepping through code, you often don’t want to have to step through every instruction of every function. Well-tested functions are usually a waste of time to step through except on rare occasion. Therefore, if you use the nexti command instead of the stepi command, GDB will wait until completion of the function before going on. Otherwise, with stepi , GDB would step you through every instruction within every called function.
Warning
One problem that GDB has is with handling interrupts. Often times GDB will miss the instruction that immediately follows an interrupt. The instruction is actually executed, but GDB doesn’t step through it. This should not be a problem - just be aware that it may happen.
14.5.2. GDB Quick-Reference¶
This quick-reference table is copyright 2002 Robert M. Dondero, Jr., and is used by permission in this book. Parameters listed in brackets are optional.
|
Exit GDB |
|
Print description of debugger command |
|
Add directories dir1 , dir2 , etc. to the list of directories searched for source files. |
|
Run the program with command line arguments arg1 , arg2 , etc. |
|
Set the program’s command-line arguments to arg1 , arg2 , etc. |
|
Print the program’s command-line arguments. |
|
Print a list of all breakpoints and their numbers (breakpoint numbers are used for other breakpoint commands). |
|
Set a breakpoint at line number linenum. |
|
Set a breakpoint at memory address addr. |
|
Set a breakpoint at the beginning of function fn. |
|
Break at breakpoint bpnum only if expression expr is non-zero. |
|
Execute commands cmd1, cmd2, etc. whenever breakpoint bpnum (or the current breakpoint) is hit. |
|
Continue executing the program. |
|
Stop executing the program. |
|
Delete breakpoints bpnum1, bpnum2, etc., or all breakpoints if none specified. |
|
Clear the breakpoint at memory address addr. |
|
Clear the breakpoint at function fn, or the current breakpoint. |
|
Clear the breakpoint at line number linenum. |
|
Disable breakpoints bpnum1, bpnum2, etc., or all breakpoints if none specified. |
|
Enable breakpoints bpnum1, bpnum2, etc., or all breakpoints if none specified. |
|
“Step over” the next instruction (doesn’t follow function calls). |
|
“Step into” the next instruction (follows function calls). |
|
“Step out” of the current function. |
|
Print the contents of all registers. |
|
Print the contents of register reg using format f. The format can be x (hexadecimal), u (unsigned decimal), o (octal), a(address), c (character), or f (floating point). |
|
Print the contents of memory address addr using repeat count r, size s, and format f. Repeat count defaults to 1 if not specified. Size can be b (byte), h (halfword), w (word), or g (double word). Size defaults to word if not specified. Format is the same as for print, with the additions of s (string) and i (instruction). |
|
Shows a numbered list of expressions set up to display automatically at each break. |
|
At each break, print the contents of register reg using format f . |
|
At each break, print the contents of memory address addr using size s (same options as for the x command). |
|
At each break, print the string of size s that begins in memory address addr. |
|
Remove displaynum from the display list. |
|
Print the call stack. |
|
Print the call stack. |
|
Print the top of the call stack. |
|
Move the context toward the bottom of the call stack. |
|
Move the context toward the top of the call stack. |
14.6. Document History¶
12/17/2002 - Version 0.5 - Initial posting of book under GNU FDL
07/18/2003 - Version 0.6 - Added ASCII appendix, finished the discussion of the CPU in the Memory chapter, reworked exercises into a new format, corrected several errors. Thanks to Harald Korneliussen for the many suggestions and the ASCII table.
01/11/2004 - Version 0.7 - Added C translation appendix, added the beginnings of an appendix of x86 instructions, added the beginnings of a GDB appendix, finished out the files chapter, finished out the counting chapter, added a records chapter, created a source file of common linux definitions, corrected several errors, and lots of other fixes
01/22/2004 - Version 0.8 - Finished GDB appendix, mostly finished w/ appendix of x86 instructions, added section on planning programs, added lots of review questions, and got everything to a completed, initial draft state.
01/29/2004 - Version 0.9 - Lots of editting of all chapters. Made code more consistent and made explanations clearer. Added some illustrations.
01/31/2004 - Version 1.0 - Rewrote chapter 9. Added full index. Lots of minor corrections.
14.7. GNU Free Documentation License¶
GNU Free Documentation License
Version 1.3, 3 November 2008
Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
<http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
0. PREAMBLE
The purpose of this License is to make a manual, textbook, or other
functional and useful document "free" in the sense of freedom: to
assure everyone the effective freedom to copy and redistribute it,
with or without modifying it, either commercially or noncommercially.
Secondarily, this License preserves for the author and publisher a way
to get credit for their work, while not being considered responsible
for modifications made by others.
This License is a kind of "copyleft", which means that derivative
works of the document must themselves be free in the same sense. It
complements the GNU General Public License, which is a copyleft
license designed for free software.
We have designed this License in order to use it for manuals for free
software, because free software needs free documentation: a free
program should come with manuals providing the same freedoms that the
software does. But this License is not limited to software manuals;
it can be used for any textual work, regardless of subject matter or
whether it is published as a printed book. We recommend this License
principally for works whose purpose is instruction or reference.
1. APPLICABILITY AND DEFINITIONS
This License applies to any manual or other work, in any medium, that
contains a notice placed by the copyright holder saying it can be
distributed under the terms of this License. Such a notice grants a
world-wide, royalty-free license, unlimited in duration, to use that
work under the conditions stated herein. The "Document", below,
refers to any such manual or work. Any member of the public is a
licensee, and is addressed as "you". You accept the license if you
copy, modify or distribute the work in a way requiring permission
under copyright law.
A "Modified Version" of the Document means any work containing the
Document or a portion of it, either copied verbatim, or with
modifications and/or translated into another language.
A "Secondary Section" is a named appendix or a front-matter section of
the Document that deals exclusively with the relationship of the
publishers or authors of the Document to the Document's overall
subject (or to related matters) and contains nothing that could fall
directly within that overall subject. (Thus, if the Document is in
part a textbook of mathematics, a Secondary Section may not explain
any mathematics.) The relationship could be a matter of historical
connection with the subject or with related matters, or of legal,
commercial, philosophical, ethical or political position regarding
them.
The "Invariant Sections" are certain Secondary Sections whose titles
are designated, as being those of Invariant Sections, in the notice
that says that the Document is released under this License. If a
section does not fit the above definition of Secondary then it is not
allowed to be designated as Invariant. The Document may contain zero
Invariant Sections. If the Document does not identify any Invariant
Sections then there are none.
The "Cover Texts" are certain short passages of text that are listed,
as Front-Cover Texts or Back-Cover Texts, in the notice that says that
the Document is released under this License. A Front-Cover Text may
be at most 5 words, and a Back-Cover Text may be at most 25 words.
A "Transparent" copy of the Document means a machine-readable copy,
represented in a format whose specification is available to the
general public, that is suitable for revising the document
straightforwardly with generic text editors or (for images composed of
pixels) generic paint programs or (for drawings) some widely available
drawing editor, and that is suitable for input to text formatters or
for automatic translation to a variety of formats suitable for input
to text formatters. A copy made in an otherwise Transparent file
format whose markup, or absence of markup, has been arranged to thwart
or discourage subsequent modification by readers is not Transparent.
An image format is not Transparent if used for any substantial amount
of text. A copy that is not "Transparent" is called "Opaque".
Examples of suitable formats for Transparent copies include plain
ASCII without markup, Texinfo input format, LaTeX input format, SGML
or XML using a publicly available DTD, and standard-conforming simple
HTML, PostScript or PDF designed for human modification. Examples of
transparent image formats include PNG, XCF and JPG. Opaque formats
include proprietary formats that can be read and edited only by
proprietary word processors, SGML or XML for which the DTD and/or
processing tools are not generally available, and the
machine-generated HTML, PostScript or PDF produced by some word
processors for output purposes only.
The "Title Page" means, for a printed book, the title page itself,
plus such following pages as are needed to hold, legibly, the material
this License requires to appear in the title page. For works in
formats which do not have any title page as such, "Title Page" means
the text near the most prominent appearance of the work's title,
preceding the beginning of the body of the text.
The "publisher" means any person or entity that distributes copies of
the Document to the public.
A section "Entitled XYZ" means a named subunit of the Document whose
title either is precisely XYZ or contains XYZ in parentheses following
text that translates XYZ in another language. (Here XYZ stands for a
specific section name mentioned below, such as "Acknowledgements",
"Dedications", "Endorsements", or "History".) To "Preserve the Title"
of such a section when you modify the Document means that it remains a
section "Entitled XYZ" according to this definition.
The Document may include Warranty Disclaimers next to the notice which
states that this License applies to the Document. These Warranty
Disclaimers are considered to be included by reference in this
License, but only as regards disclaiming warranties: any other
implication that these Warranty Disclaimers may have is void and has
no effect on the meaning of this License.
2. VERBATIM COPYING
You may copy and distribute the Document in any medium, either
commercially or noncommercially, provided that this License, the
copyright notices, and the license notice saying this License applies
to the Document are reproduced in all copies, and that you add no
other conditions whatsoever to those of this License. You may not use
technical measures to obstruct or control the reading or further
copying of the copies you make or distribute. However, you may accept
compensation in exchange for copies. If you distribute a large enough
number of copies you must also follow the conditions in section 3.
You may also lend copies, under the same conditions stated above, and
you may publicly display copies.
3. COPYING IN QUANTITY
If you publish printed copies (or copies in media that commonly have
printed covers) of the Document, numbering more than 100, and the
Document's license notice requires Cover Texts, you must enclose the
copies in covers that carry, clearly and legibly, all these Cover
Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
the back cover. Both covers must also clearly and legibly identify
you as the publisher of these copies. The front cover must present
the full title with all words of the title equally prominent and
visible. You may add other material on the covers in addition.
Copying with changes limited to the covers, as long as they preserve
the title of the Document and satisfy these conditions, can be treated
as verbatim copying in other respects.
If the required texts for either cover are too voluminous to fit
legibly, you should put the first ones listed (as many as fit
reasonably) on the actual cover, and continue the rest onto adjacent
pages.
If you publish or distribute Opaque copies of the Document numbering
more than 100, you must either include a machine-readable Transparent
copy along with each Opaque copy, or state in or with each Opaque copy
a computer-network location from which the general network-using
public has access to download using public-standard network protocols
a complete Transparent copy of the Document, free of added material.
If you use the latter option, you must take reasonably prudent steps,
when you begin distribution of Opaque copies in quantity, to ensure
that this Transparent copy will remain thus accessible at the stated
location until at least one year after the last time you distribute an
Opaque copy (directly or through your agents or retailers) of that
edition to the public.
It is requested, but not required, that you contact the authors of the
Document well before redistributing any large number of copies, to
give them a chance to provide you with an updated version of the
Document.
4. MODIFICATIONS
You may copy and distribute a Modified Version of the Document under
the conditions of sections 2 and 3 above, provided that you release
the Modified Version under precisely this License, with the Modified
Version filling the role of the Document, thus licensing distribution
and modification of the Modified Version to whoever possesses a copy
of it. In addition, you must do these things in the Modified Version:
A. Use in the Title Page (and on the covers, if any) a title distinct
from that of the Document, and from those of previous versions
(which should, if there were any, be listed in the History section
of the Document). You may use the same title as a previous version
if the original publisher of that version gives permission.
B. List on the Title Page, as authors, one or more persons or entities
responsible for authorship of the modifications in the Modified
Version, together with at least five of the principal authors of the
Document (all of its principal authors, if it has fewer than five),
unless they release you from this requirement.
C. State on the Title page the name of the publisher of the
Modified Version, as the publisher.
D. Preserve all the copyright notices of the Document.
E. Add an appropriate copyright notice for your modifications
adjacent to the other copyright notices.
F. Include, immediately after the copyright notices, a license notice
giving the public permission to use the Modified Version under the
terms of this License, in the form shown in the Addendum below.
G. Preserve in that license notice the full lists of Invariant Sections
and required Cover Texts given in the Document's license notice.
H. Include an unaltered copy of this License.
I. Preserve the section Entitled "History", Preserve its Title, and add
to it an item stating at least the title, year, new authors, and
publisher of the Modified Version as given on the Title Page. If
there is no section Entitled "History" in the Document, create one
stating the title, year, authors, and publisher of the Document as
given on its Title Page, then add an item describing the Modified
Version as stated in the previous sentence.
J. Preserve the network location, if any, given in the Document for
public access to a Transparent copy of the Document, and likewise
the network locations given in the Document for previous versions
it was based on. These may be placed in the "History" section.
You may omit a network location for a work that was published at
least four years before the Document itself, or if the original
publisher of the version it refers to gives permission.
K. For any section Entitled "Acknowledgements" or "Dedications",
Preserve the Title of the section, and preserve in the section all
the substance and tone of each of the contributor acknowledgements
and/or dedications given therein.
L. Preserve all the Invariant Sections of the Document,
unaltered in their text and in their titles. Section numbers
or the equivalent are not considered part of the section titles.
M. Delete any section Entitled "Endorsements". Such a section
may not be included in the Modified Version.
N. Do not retitle any existing section to be Entitled "Endorsements"
or to conflict in title with any Invariant Section.
O. Preserve any Warranty Disclaimers.
If the Modified Version includes new front-matter sections or
appendices that qualify as Secondary Sections and contain no material
copied from the Document, you may at your option designate some or all
of these sections as invariant. To do this, add their titles to the
list of Invariant Sections in the Modified Version's license notice.
These titles must be distinct from any other section titles.
You may add a section Entitled "Endorsements", provided it contains
nothing but endorsements of your Modified Version by various
parties--for example, statements of peer review or that the text has
been approved by an organization as the authoritative definition of a
standard.
You may add a passage of up to five words as a Front-Cover Text, and a
passage of up to 25 words as a Back-Cover Text, to the end of the list
of Cover Texts in the Modified Version. Only one passage of
Front-Cover Text and one of Back-Cover Text may be added by (or
through arrangements made by) any one entity. If the Document already
includes a cover text for the same cover, previously added by you or
by arrangement made by the same entity you are acting on behalf of,
you may not add another; but you may replace the old one, on explicit
permission from the previous publisher that added the old one.
The author(s) and publisher(s) of the Document do not by this License
give permission to use their names for publicity for or to assert or
imply endorsement of any Modified Version.
5. COMBINING DOCUMENTS
You may combine the Document with other documents released under this
License, under the terms defined in section 4 above for modified
versions, provided that you include in the combination all of the
Invariant Sections of all of the original documents, unmodified, and
list them all as Invariant Sections of your combined work in its
license notice, and that you preserve all their Warranty Disclaimers.
The combined work need only contain one copy of this License, and
multiple identical Invariant Sections may be replaced with a single
copy. If there are multiple Invariant Sections with the same name but
different contents, make the title of each such section unique by
adding at the end of it, in parentheses, the name of the original
author or publisher of that section if known, or else a unique number.
Make the same adjustment to the section titles in the list of
Invariant Sections in the license notice of the combined work.
In the combination, you must combine any sections Entitled "History"
in the various original documents, forming one section Entitled
"History"; likewise combine any sections Entitled "Acknowledgements",
and any sections Entitled "Dedications". You must delete all sections
Entitled "Endorsements".
6. COLLECTIONS OF DOCUMENTS
You may make a collection consisting of the Document and other
documents released under this License, and replace the individual
copies of this License in the various documents with a single copy
that is included in the collection, provided that you follow the rules
of this License for verbatim copying of each of the documents in all
other respects.
You may extract a single document from such a collection, and
distribute it individually under this License, provided you insert a
copy of this License into the extracted document, and follow this
License in all other respects regarding verbatim copying of that
document.
7. AGGREGATION WITH INDEPENDENT WORKS
A compilation of the Document or its derivatives with other separate
and independent documents or works, in or on a volume of a storage or
distribution medium, is called an "aggregate" if the copyright
resulting from the compilation is not used to limit the legal rights
of the compilation's users beyond what the individual works permit.
When the Document is included in an aggregate, this License does not
apply to the other works in the aggregate which are not themselves
derivative works of the Document.
If the Cover Text requirement of section 3 is applicable to these
copies of the Document, then if the Document is less than one half of
the entire aggregate, the Document's Cover Texts may be placed on
covers that bracket the Document within the aggregate, or the
electronic equivalent of covers if the Document is in electronic form.
Otherwise they must appear on printed covers that bracket the whole
aggregate.
8. TRANSLATION
Translation is considered a kind of modification, so you may
distribute translations of the Document under the terms of section 4.
Replacing Invariant Sections with translations requires special
permission from their copyright holders, but you may include
translations of some or all Invariant Sections in addition to the
original versions of these Invariant Sections. You may include a
translation of this License, and all the license notices in the
Document, and any Warranty Disclaimers, provided that you also include
the original English version of this License and the original versions
of those notices and disclaimers. In case of a disagreement between
the translation and the original version of this License or a notice
or disclaimer, the original version will prevail.
If a section in the Document is Entitled "Acknowledgements",
"Dedications", or "History", the requirement (section 4) to Preserve
its Title (section 1) will typically require changing the actual
title.
9. TERMINATION
You may not copy, modify, sublicense, or distribute the Document
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense, or distribute it is void, and
will automatically terminate your rights under this License.
However, if you cease all violation of this License, then your license
from a particular copyright holder is reinstated (a) provisionally,
unless and until the copyright holder explicitly and finally
terminates your license, and (b) permanently, if the copyright holder
fails to notify you of the violation by some reasonable means prior to
60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, receipt of a copy of some or all of the same material does
not give you any rights to use it.
10. FUTURE REVISIONS OF THIS LICENSE
The Free Software Foundation may publish new, revised versions of the
GNU Free Documentation License from time to time. Such new versions
will be similar in spirit to the present version, but may differ in
detail to address new problems or concerns. See
http://www.gnu.org/copyleft/.
Each version of the License is given a distinguishing version number.
If the Document specifies that a particular numbered version of this
License "or any later version" applies to it, you have the option of
following the terms and conditions either of that specified version or
of any later version that has been published (not as a draft) by the
Free Software Foundation. If the Document does not specify a version
number of this License, you may choose any version ever published (not
as a draft) by the Free Software Foundation. If the Document
specifies that a proxy can decide which future versions of this
License can be used, that proxy's public statement of acceptance of a
version permanently authorizes you to choose that version for the
Document.
11. RELICENSING
"Massive Multiauthor Collaboration Site" (or "MMC Site") means any
World Wide Web server that publishes copyrightable works and also
provides prominent facilities for anybody to edit those works. A
public wiki that anybody can edit is an example of such a server. A
"Massive Multiauthor Collaboration" (or "MMC") contained in the site
means any set of copyrightable works thus published on the MMC site.
"CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0
license published by Creative Commons Corporation, a not-for-profit
corporation with a principal place of business in San Francisco,
California, as well as future copyleft versions of that license
published by that same organization.
"Incorporate" means to publish or republish a Document, in whole or in
part, as part of another Document.
An MMC is "eligible for relicensing" if it is licensed under this
License, and if all works that were first published under this License
somewhere other than this MMC, and subsequently incorporated in whole or
in part into the MMC, (1) had no cover texts or invariant sections, and
(2) were thus incorporated prior to November 1, 2008.
The operator of an MMC Site may republish an MMC contained in the site
under CC-BY-SA on the same site at any time before August 1, 2009,
provided the MMC is eligible for relicensing.
ADDENDUM: How to use this License for your documents
To use this License in a document you have written, include a copy of
the License in the document and put the following copyright and
license notices just after the title page:
Copyright (c) YEAR YOUR NAME.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled "GNU
Free Documentation License".
If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
replace the "with...Texts." line with this:
with the Invariant Sections being LIST THEIR TITLES, with the
Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
If you have Invariant Sections without Cover Texts, or some other
combination of the three, merge those two alternatives to suit the
situation.
If your document contains nontrivial examples of program code, we
recommend releasing these examples in parallel under your choice of
free software license, such as the GNU General Public License,
to permit their use in free software.
14.8. Personal Dedication¶
There are so many people I could thank. I will name here but a few of the people who have brought me to where I am today. The many family members, Sunday School teachers, youth pastors, school teachers, friends, and other relationships that God has brought into my life to lead me, help me, and teach me are too many to count. This book is dedicated to you all.
There are some people, however, that I would like to thank specifically.
First of all, I want to thank the members of the Vineyard Christian Fellowship Church in Champaign, Illinois for everything that you have done to help me and my family in our times of crisis. It’s been a long time since I’ve seen or heard from any of you, but I think about you always. You have been such a blessing to me, my wife, and Daniel, and I could never thank you enough for showing us Christ’s love when we needed it most. I thank God every time I think of you - I thank Him for bringing you all to us in our deepest times of need. Even out in the middle of Illinois with no friends of family, God showed that He was still watching after us. Thank you for being His hands on Earth. Specifically, I’d like to thank Joe and Rhonda, Pam and Dell, and Herschel and Vicki. There were many, many others, too - so many people helped us that it would be impossible to list them all.
I also want to thank my parents, who gave me the example of perserverance and strength in hard times. Your example has helped me be a good father to my children, and a good husband to my wife.
I also want to thank my wife, who even from when we first started dating encouraged me to seek God in everything. Thank you for your support in writing this book, and more importantly, for your support in being obedient to God.
I also want to thanks the Little Light House school. My entire family is continually blessed by the help you give to our son.
I also want to thank Joe and D.A. Thank you for taking a chance on me in ministry. Being able to be a part of God’s ministry again has helped me in so many ways.
You all have given me the strength I needed to write this book over the last few years. Without your support, I would have been too overwhelmed by personal crises to even think about anything more than getting through a day, much less putting this book together. You have all been a great blessing to me, and I will keep you in my prayers always.
Footnotes
- 1
Note that different versions of GCC do this differently.