<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1626185782516232162</id><updated>2012-01-11T00:31:25.690-08:00</updated><category term='arm'/><category term='wiki'/><category term='jdbc'/><category term='backport'/><category term='OpenACS'/><category term='x86'/><category term='buildroot'/><category term='gnu'/><category term='uboot'/><category term='assembly'/><category term='exceptions'/><category term='inotify'/><category term='firefox'/><category term='bootmem'/><category term='as'/><category term='git'/><category term='virtual pc'/><category term='wikimedia'/><category term='viewcvs'/><category term='debian'/><category term='freebsd'/><category term='ld'/><category term='greasemonkey'/><category term='car'/><category term='linux'/><category term='TR-069'/><category term='binutils'/><category term='cvs'/><category term='gdb'/><category term='java'/><category term='mysql'/><category term='vmware'/><category term='dnotify'/><category term='interrupts'/><category term='linkers'/><category term='memory'/><category term='loaders'/><category term='c'/><category term='mantis'/><category term='viewvc'/><category term='mips'/><category term='filesystem'/><category term='linking'/><category term='kernel'/><category term='jboss'/><category term='nm'/><category term='gcc'/><category term='qemu'/><category term='c99'/><title type='text'>Winfred C. H. Lu</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://winfred-lu.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://winfred-lu.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Winfred</name><uri>http://www.blogger.com/profile/15649970719010644298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm2.static.flickr.com/1104/569054989_83809a02b2_m.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>17</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1626185782516232162.post-6504342758165065831</id><published>2011-12-29T02:44:00.000-08:00</published><updated>2012-01-05T00:08:04.518-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='arm'/><category scheme='http://www.blogger.com/atom/ns#' term='gnu'/><category scheme='http://www.blogger.com/atom/ns#' term='gcc'/><category scheme='http://www.blogger.com/atom/ns#' term='uboot'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='binutils'/><category scheme='http://www.blogger.com/atom/ns#' term='qemu'/><category scheme='http://www.blogger.com/atom/ns#' term='gdb'/><category scheme='http://www.blogger.com/atom/ns#' term='buildroot'/><title type='text'>GDB Debugging ARM U-Boot on QEMU</title><content type='html'>&lt;div class="outline-2" id="outline-container-1"&gt;
&lt;h2 id="sec-1"&gt;


&lt;span class="section-number-2"&gt;1&lt;/span&gt; Introduction &lt;/h2&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="outline-text-2" id="text-1"&gt;
QEMU is a generic and open source machine emulator and virtualizer.
In this article, we will use it as a machine emulator and run the U-Boot on top of it.
It will also be demonstrated about how to debug U-Boot with GDB.
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="outline-2" id="outline-container-2"&gt;
&lt;h2 id="sec-2"&gt;


&lt;a name='more'&gt;&lt;/a&gt;


&lt;span class="section-number-2"&gt;2&lt;/span&gt; Installation and Compilation &lt;/h2&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="outline-text-2" id="text-2"&gt;
&lt;/div&gt;
&lt;div class="outline-3" id="outline-container-2.1"&gt;
&lt;h3 id="sec-2.1"&gt;


&lt;span class="section-number-3"&gt;2.1&lt;/span&gt; Cross Toolchain &lt;/h3&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="outline-text-3" id="text-2.1"&gt;
Install one of the cross toolchain accordingly. available toolchains:
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://www.denx.de/"&gt;DENX&lt;/a&gt; - &lt;a href="http://www.denx.de/wiki/ELDK-5"&gt;ELDK (Embedded Linux Development Kit)&lt;/a&gt; : &lt;a href="http://www.denx.de/wiki/ELDK-5/WebHome"&gt;document&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.mentor.com/"&gt;Mentor Graphics&lt;/a&gt; - &lt;a href="https://sourcery.mentor.com/sgpp/lite/arm/portal/subscription?@template=lite"&gt;Sourcery ARM EABI toolchain&lt;/a&gt; : &lt;a href="https://sourcery.mentor.com/sgpp/lite/arm/portal/doc13007/getting-started.pdf"&gt;document&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://buildroot.uclibc.org/"&gt;BuildRoot&lt;/a&gt; - &lt;a href="http://buildroot.uclibc.org/downloads/buildroot-2011.11.tar.bz2"&gt;buildroot-2011.11.tar.bz2&lt;/a&gt; : &lt;a href="http://buildroot.uclibc.org/downloads/buildroot.html"&gt;document&lt;/a&gt;

&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="outline-3" id="outline-container-2.2"&gt;
&lt;h3 id="sec-2.2"&gt;


&lt;span class="section-number-3"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h3 id="sec-2.2"&gt;


&lt;span class="section-number-3"&gt;2.2&lt;/span&gt; QEMU package &lt;/h3&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="outline-text-3" id="text-2.2"&gt;
Install Debian QEMU package.
&lt;br /&gt;
&lt;pre class="example"&gt;&lt;span class="Apple-style-span" style="color: purple;"&gt;# apt-get install qemu
&lt;/span&gt;&lt;/pre&gt;
Or on a host running Ubuntu, try
&lt;br /&gt;
&lt;pre class="example"&gt;$ sudo apt-get install qemu-kvm-extras
&lt;/pre&gt;
We may also check if ARM versatilePB is supported by QEMU.
&lt;br /&gt;
&lt;pre class="example"&gt;$ qemu-system-arm -M \?
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="outline-3" id="outline-container-2.3"&gt;
&lt;h3 id="sec-2.3"&gt;


&lt;span class="section-number-3"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h3 id="sec-2.3"&gt;


&lt;span class="section-number-3"&gt;2.3&lt;/span&gt; Download U-Boot &lt;/h3&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="outline-text-3" id="text-2.3"&gt;
Fetch the current Das U-Boot source code through git.
&lt;br /&gt;
&lt;pre class="example"&gt;&lt;span class="Apple-style-span" style="color: purple;"&gt;$ git clone git://git.denx.de/u-boot.git
&lt;/span&gt;&lt;/pre&gt;
Or download a released version from &lt;a href="ftp://ftp.denx.de/pub/u-boot/"&gt;ftp site&lt;/a&gt;.
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="outline-3" id="outline-container-2.4"&gt;
&lt;h3 id="sec-2.4"&gt;


&lt;span class="section-number-3"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h3 id="sec-2.4"&gt;


&lt;span class="section-number-3"&gt;2.4&lt;/span&gt; Compile U-Boot. &lt;/h3&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="outline-text-3" id="text-2.4"&gt;
&lt;pre class="example"&gt;$ cd u-boot/
&lt;span class="Apple-style-span" style="color: purple;"&gt;$ make versatileqemu_config&lt;/span&gt;
$ make
&lt;/pre&gt;
Or if a cross toolchain with different prefix is used, ELDK's "arm-linux-gnueabi-" for example,
&lt;br /&gt;
&lt;pre class="example"&gt;$ make CROSS_COMPILE=arm-linux-gnueabi-
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="outline-2" id="outline-container-3"&gt;
&lt;h2 id="sec-3"&gt;


&lt;span class="section-number-2"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h2 id="sec-3"&gt;


&lt;span class="section-number-2"&gt;3&lt;/span&gt; Testing and Debugging &lt;/h2&gt;
&lt;div class="outline-text-2" id="text-3"&gt;
&lt;/div&gt;
&lt;div class="outline-3" id="outline-container-3.1"&gt;
&lt;h3 id="sec-3.1"&gt;


&lt;span class="section-number-3"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h3 id="sec-3.1"&gt;


&lt;span class="section-number-3"&gt;3.1&lt;/span&gt; Normal Mode &lt;/h3&gt;
&lt;div class="outline-text-3" id="text-3.1"&gt;
&lt;br /&gt;
We can execute QEMU to run U-Boot for ARM, then develop and debug as we wish.
&lt;br /&gt;
&lt;pre class="example"&gt;&lt;span class="Apple-style-span" style="color: purple;"&gt;$ qemu-system-arm -nographic -M versatilepb -m 128 -kernel u-boot
&lt;/span&gt;U-Boot 2011.12-00046-gbfcc40b-dirty (Dec 26 2011 - 18:11:37)

DRAM:  128 MiB
WARNING: Caches not enabled
Using default environment

In:    serial
Out:   serial
Err:   serial
Net:   SMC91111-0
Warning: failed to set MAC address

VersatilePB #
&lt;/pre&gt;
&lt;br /&gt;
A list of u-boot commands and environment variables,
&lt;br /&gt;
&lt;pre class="example"&gt;VersatilePB # help
?       - alias for 'help'
base    - print or set address offset
bdinfo  - print Board Info structure
bootm   - boot application image from memory
bootp   - boot image via network using BOOTP/TFTP protocol
cmp     - memory compare
cp      - memory copy
crc32   - checksum calculation
dhcp    - boot image via network using DHCP/TFTP protocol
env     - environment handling commands
erase   - erase FLASH memory
flinfo  - print FLASH memory information
go      - start application at address 'addr'
help    - print command description/usage
iminfo  - print header information for application image
loop    - infinite loop on address range
md      - memory display
mm      - memory modify (auto-incrementing address)
mtest   - simple RAM read/write test
mw      - memory write (fill)
nm      - memory modify (constant address)
ping    - send ICMP ECHO_REQUEST to network host
printenv- print environment variables
protect - enable or disable FLASH write protection
reset   - Perform RESET of the CPU
setenv  - set environment variables
tftpboot- boot image via network using TFTP protocol
version - print monitor, compiler and linker version
VersatilePB #
VersatilePB # printenv
baudrate=38400
bootargs=root=/dev/nfs mem=128M ip=dhcp netdev=25,0,0xf1010000,0xf1010010,eth0
bootdelay=2
bootfile=/tftpboot/uImage
ethact=SMC91111-0
stderr=serial
stdin=serial
stdout=serial
verify=n

Environment size: 219/8188 bytes
VersatilePB #
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="outline-3" id="outline-container-3.2"&gt;
&lt;h3 id="sec-3.2"&gt;


&lt;span class="section-number-3"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h3 id="sec-3.2"&gt;


&lt;span class="section-number-3"&gt;3.2&lt;/span&gt; Debugging with GDB &lt;/h3&gt;
&lt;div class="outline-text-3" id="text-3.2"&gt;
&lt;br /&gt;
While QEMU's built-in monitor provides limited debugging support,
it can act as a remote debugging target for GDB.
&lt;br /&gt;
&lt;pre class="example"&gt;&lt;span class="Apple-style-span" style="color: purple;"&gt;$ qemu-system-arm -nographic -M versatilepb -m 128 -kernel u-boot &lt;/span&gt;&lt;span class="Apple-style-span" style="color: red;"&gt;-S -s&lt;/span&gt;&lt;span class="Apple-style-span" style="color: purple;"&gt;
&lt;/span&gt;&lt;/pre&gt;
'-S' tells QEMU not to start CPU at startup. We must type 'c' in monitor to let it continue.
'-s' is shorthand for '-gdb tcp::1234', telling QEMU to wait for gdb connection on TCP port 1234.
&lt;br /&gt;
&lt;br /&gt;
On the other hand, we start the ARM GDB and set target to TCP port 1234 as well.
&lt;br /&gt;
&lt;pre class="example"&gt;&lt;span class="Apple-style-span" style="color: purple;"&gt;$ arm-linux-gnueabi-gdb u-boot
&lt;/span&gt;GNU gdb (GDB) 7.3
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later &amp;lt;http://gnu.org/licenses/gpl.html&amp;gt;
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-eldk-linux --target=arm-linux-gnueabi".
For bug reporting instructions, please see:
&amp;lt;http://www.gnu.org/software/gdb/bugs/&amp;gt;...
Reading symbols from /home/winfred/u-boot/u-boot...done.
(gdb) target remote :1234
Remote debugging using :1234
_start () at start.S:64
64              b       reset
(gdb)
&lt;/pre&gt;
&lt;br /&gt;
We are able to use GDB for source level debugging now.
&lt;br /&gt;
&lt;pre class="example"&gt;(gdb) n
188             mrs     r0,cpsr
(gdb) n
189             bic     r0,r0,#0x1f
(gdb) b board_init_f
Breakpoint 1 at 0x10b70: file board.c, line 270.
(gdb) c
Continuing.

Breakpoint 1, board_init_f (bootflag=0) at board.c:270
270             gd = (gd_t *) ((CONFIG_SYS_INIT_SP_ADDR) &amp;amp; ~0x07);
(gdb)
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="outline-3" id="outline-container-3.3"&gt;
&lt;h3 id="sec-3.3"&gt;


&lt;span class="section-number-3"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h3 id="sec-3.3"&gt;


&lt;span class="section-number-3"&gt;3.3&lt;/span&gt; Debugging After Relocation &lt;/h3&gt;
&lt;div class="outline-text-3" id="text-3.3"&gt;
&lt;br /&gt;
In order to debug U-Boot after relocation, we need to know the address which U-Boot relocates itself to.
There are couple of ways to get it,
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;
Get it from U-Boot 'bdinfo' command.



&lt;pre class="example"&gt;&lt;span class="Apple-style-span" style="color: purple;"&gt;VersatilePB # bdinfo
&lt;/span&gt;arch_number = 0x00000183
boot_params = 0x00000100
DRAM bank   = 0x00000000
-&amp;gt; start    = 0x00000000
-&amp;gt; size     = 0x08000000
ethaddr     = (not set)
ip_addr     = 0.0.0.0
baudrate    = 38400 bps
TLB addr    = 0x07FF0000
relocaddr   = &lt;span class="Apple-style-span" style="color: red;"&gt;0x07FC5000&lt;/span&gt;
reloc off   = 0x07FB5000
irq_sp      = 0x07FA2F70
sp start    = 0x07FA2F60
FB base     = 0x00000000
VersatilePB #
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
Print the value of gd-&amp;gt;relocaddr.
Since gd is avalable after board_init_f(), and it is storeed in register $r1,



&lt;pre class="example"&gt;(gdb) b relocate_code
Breakpoint 1 at 0x1007c: file start.S, line 226.
(gdb) c
Continuing.

Breakpoint 1, relocate_code () at start.S:226
226             mov     r5, r1  /* save addr of gd */
&lt;span class="Apple-style-span" style="color: purple;"&gt;(gdb) p/x ((gd_t *)$r1)-&amp;gt;relocaddr
&lt;/span&gt;$1 = &lt;span class="Apple-style-span" style="color: red;"&gt;0x7fc5000&lt;/span&gt;
(gdb)
&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
Having the relocated address, we need to reload the symbol file accordingly.
&lt;br /&gt;
&lt;pre class="example"&gt;(gdb) d
Delete all breakpoints? (y or n) y
&lt;span class="Apple-style-span" style="color: purple;"&gt;(gdb) symbol-file
&lt;/span&gt;Discard symbol table from `/home/winfred/u-boot/u-boot'? (y or n) y
No symbol file now.
&lt;span class="Apple-style-span" style="color: purple;"&gt;(gdb) add-symbol-file u-boot 0x7fc5000
&lt;/span&gt;add symbol table from file "u-boot" at
.text_addr = 0x7fc5000
(y or n) y
Reading symbols from /home/winfred/u-boot/u-boot...done.
(gdb)
&lt;/pre&gt;
&lt;br /&gt;
Then, debug U-Boot after relocation. Let's try to break at the first function after the relocation,
&lt;br /&gt;
&lt;pre class="example"&gt;(gdb) b board_init_r
Breakpoint 2 at 0x7fc5d64: file board.c, line 455.
(gdb) c
Continuing.

Breakpoint 2, board_init_r (id=0x7fa2f70, dest_addr=133976064) at board.c:455
455             gd = id;
(gdb)
&lt;/pre&gt;
&lt;br /&gt;
Happy debugging.
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="outline-2" id="outline-container-4"&gt;
&lt;h2 id="sec-4"&gt;


&lt;span class="section-number-2"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h2 id="sec-4"&gt;


&lt;span class="section-number-2"&gt;4&lt;/span&gt; Reference &lt;/h2&gt;
&lt;div class="outline-text-2" id="text-4"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://balau82.wordpress.com/2010/03/10/u-boot-for-arm-on-qemu/"&gt;Balau, U-boot for ARM on QEMU&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://balau82.wordpress.com/2010/04/12/booting-linux-with-u-boot-on-qemu-arm/"&gt;Balau, Booting Linux with U-Boot on QEMU ARM&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://files.meetup.com/1590495/debugging-with-qemu.pdf"&gt;Khem Raj, Debugging Linux systems using GDB and QEMU&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://wiki.qemu.org/Manual"&gt;QEMU Documentation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.denx.de/wiki/U-Boot/Documentation"&gt;U-Boot Documentation&lt;/a&gt; - &lt;a href="http://www.denx.de/wiki/DULG/DebuggingUBoot"&gt;Debugging UBoot&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://[[http://www.gnu.org/software/gdb/documentation/"&gt;http://www.gnu.org/software/gdb/documentation/&lt;/a&gt;][GDB Documentation]] - &lt;a href="http://sourceware.org/gdb/current/onlinedocs/gdb/Remote-Debugging.html#Remote-Debugging"&gt;Debugging Remote Programs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="postamble"&gt;
&lt;div class="author"&gt;
Date: 2011-12-26 Thu&lt;/div&gt;
&lt;div class="creator"&gt;
HTML generated by org-mode 6.33x in emacs 23&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1626185782516232162-6504342758165065831?l=winfred-lu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://winfred-lu.blogspot.com/feeds/6504342758165065831/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1626185782516232162&amp;postID=6504342758165065831' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/6504342758165065831'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/6504342758165065831'/><link rel='alternate' type='text/html' href='http://winfred-lu.blogspot.com/2011/12/arm-u-boot-on-qemu.html' title='GDB Debugging ARM U-Boot on QEMU'/><author><name>Winfred</name><uri>http://www.blogger.com/profile/15649970719010644298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm2.static.flickr.com/1104/569054989_83809a02b2_m.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1626185782516232162.post-5995259804292484465</id><published>2011-04-06T04:32:00.000-07:00</published><updated>2011-04-07T01:54:24.522-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mips'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='kernel'/><category scheme='http://www.blogger.com/atom/ns#' term='c'/><category scheme='http://www.blogger.com/atom/ns#' term='interrupts'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly'/><category scheme='http://www.blogger.com/atom/ns#' term='exceptions'/><title type='text'>MIPS Exceptions Initialization and Handling on Linux</title><content type='html'>Exceptions and interrupts are un-expected events that disrupt the normal flow of execution. Interrupts are unexpected events from outside the CPU core. Exceptions are from within the CPU, including memory translation exceptions, cache misses, unusual program conditions such as unaligned loads, system calls and traps, and so on.&lt;br /&gt;
&lt;br /&gt;
MIPS architecture adopts precise exception mechanisms, and make it easy for the software to deal with the exceptions. After any exception, CP0 EPC register points to the correct place to restart execution after the exception is dealt with.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
The followed is a brief list of MIPS exceptions in order of their relative priority.&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Reset&lt;/li&gt;
&lt;li&gt;NMI -- non-maskable interrupts&lt;/li&gt;
&lt;li&gt;Interrupt -- hardware and software interrupts&lt;/li&gt;
&lt;li&gt;AdEL -- fetch address alignment error; fetch reference to protected address&lt;/li&gt;
&lt;li&gt;TLBL -- fetch TLB miss&lt;/li&gt;
&lt;li&gt;ICache Error&lt;/li&gt;
&lt;li&gt;Sys -- execution of SYSCALL instruction&lt;/li&gt;
&lt;li&gt;Ov -- execution of an arithmetic instruction that overflowed&lt;/li&gt;
&lt;li&gt;Tr -- execution of a trap&lt;/li&gt;
&lt;li&gt;AdEL -- load address alignement error; load reference to protected address&lt;/li&gt;
&lt;li&gt;AdES -- store address alignement error; store reference to protected address&lt;/li&gt;
&lt;li&gt;TLBL -- load TLB miss&lt;/li&gt;
&lt;li&gt;TLBS -- store TLB miss&lt;/li&gt;
&lt;li&gt;DCache Error&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
MIPSr2 architecture supports 3 interrupt modes. It provides interrupt compatibility mode, which behaves identical to MIPSr1. It also supports vectored interrupt (VI) mode, and permits the use of an external interrupt controller (EIC).&lt;br /&gt;
&lt;br /&gt;
VI mode adds the ability to prioritize and vector interrupts to a handler dedicated to that interrupt. Each interrupt starts at the address according to the interrupt signal. It also allows us to configure the space between different entry points (VS of IntCtl register). In EIC mode, the six independent signals become a 6-bit binary number: Zero means no interrupt, others are 63 distinct interrupt codes.&lt;br /&gt;
&lt;br /&gt;
An exception vector is where the exception handling starts. MIPS exceptions are handled either through the general exception vector (offset 0x180), or the special interrupt vector (0x200), based on the value of IV of Cause register. Software was required to prioritize exceptions in the handler prologue.&lt;br /&gt;
&lt;br /&gt;
The followed is the table of exception entry points (vector addresses).&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://1.bp.blogspot.com/-XIjitojvfxY/TZxNngRE7pI/AAAAAAAAAWE/lA7-CIukh64/s1600/2011-04-06_192418.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="125" src="http://1.bp.blogspot.com/-XIjitojvfxY/TZxNngRE7pI/AAAAAAAAAWE/lA7-CIukh64/s320/2011-04-06_192418.png" width="384" /&gt;&lt;/a&gt;&lt;/div&gt;Where Base is 0x80000000 by default, and can be configured by VA of EBase register. And RBase is 0xBFC00000 by default, and can be changed by configuring SI_UseExceptionBase to 1. Cache error handling instructions have to be fetched through uncached KSeg1 window.&lt;br /&gt;
&lt;br /&gt;
Here is what a MIPS CPU does when it decides to take an exception:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;It sets up the EPC to point to the restart location.&lt;/li&gt;
&lt;li&gt;It force CPU into kernel mode and disables interrupts. (by setting EXL of SR register)&lt;/li&gt;
&lt;li&gt;Cause register is set up so that software can see the reason for the exception. On address exceptions, BadVAddr is also set. Memory management system exceptions set up some of the MMU registers too.&lt;/li&gt;
&lt;li&gt;CPU then starts fetching instructions from the exception entry point, and everything else is up to software.&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
So, let's see how MIPS Linux initializes handling routines and handles exceptions.&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt;  1 &lt;/span&gt;&lt;span class="Type"&gt;void&lt;/span&gt; __init trap_init(&lt;span class="Type"&gt;void&lt;/span&gt;)
&lt;span class="lnr"&gt;  2 &lt;/span&gt;{
&lt;span class="lnr"&gt;  3 &lt;/span&gt;        &lt;span class="StorageClass"&gt;extern&lt;/span&gt; &lt;span class="Type"&gt;char&lt;/span&gt; except_vec3_generic, except_vec3_r4000;
&lt;span class="lnr"&gt;  4 &lt;/span&gt;        &lt;span class="StorageClass"&gt;extern&lt;/span&gt; &lt;span class="Type"&gt;char&lt;/span&gt; except_vec4;
&lt;span class="lnr"&gt;  5 &lt;/span&gt;        &lt;span class="Type"&gt;unsigned&lt;/span&gt; &lt;span class="Type"&gt;long&lt;/span&gt; i;
&lt;span class="lnr"&gt;  6 &lt;/span&gt;        &lt;span class="Type"&gt;int&lt;/span&gt; rollback;
&lt;span class="lnr"&gt;  7 &lt;/span&gt;
&lt;span class="lnr"&gt;  8 &lt;/span&gt;        check_wait();
&lt;span class="lnr"&gt;  9 &lt;/span&gt;        rollback = (cpu_wait == r4k_wait);
&lt;span class="lnr"&gt; 10 &lt;/span&gt;
&lt;span class="lnr"&gt; 11 &lt;/span&gt;&lt;span class="PreCondit"&gt;#if defined(CONFIG_KGDB)&lt;/span&gt;
&lt;span class="lnr"&gt; 12 &lt;/span&gt;        &lt;span class="Conditional"&gt;if&lt;/span&gt; (kgdb_early_setup)
&lt;span class="lnr"&gt; 13 &lt;/span&gt;                &lt;span class="Statement"&gt;return&lt;/span&gt;;       &lt;span class="Comment"&gt;/*&lt;/span&gt;&lt;span class="Comment"&gt; Already done &lt;/span&gt;&lt;span class="Comment"&gt;*/&lt;/span&gt;
&lt;span class="lnr"&gt; 14 &lt;/span&gt;&lt;span class="PreCondit"&gt;#endif&lt;/span&gt;
&lt;span class="lnr"&gt; 15 &lt;/span&gt;
&lt;span class="lnr"&gt; 16 &lt;/span&gt;        &lt;span class="Conditional"&gt;if&lt;/span&gt; (cpu_has_veic || cpu_has_vint) {
&lt;span class="lnr"&gt; 17 &lt;/span&gt;                &lt;span class="Type"&gt;unsigned&lt;/span&gt; &lt;span class="Type"&gt;long&lt;/span&gt; size = &lt;span class="Number"&gt;0x200&lt;/span&gt; + VECTORSPACING*&lt;span class="Number"&gt;64&lt;/span&gt;;
&lt;span class="lnr"&gt; 18 &lt;/span&gt;                ebase = (&lt;span class="Type"&gt;unsigned&lt;/span&gt; &lt;span class="Type"&gt;long&lt;/span&gt;)
&lt;span class="lnr"&gt; 19 &lt;/span&gt;                        __alloc_bootmem(size, &lt;span class="Number"&gt;1&lt;/span&gt; &amp;lt;&amp;lt; fls(size), &lt;span class="Number"&gt;0&lt;/span&gt;);
&lt;span class="lnr"&gt; 20 &lt;/span&gt;        } &lt;span class="Conditional"&gt;else&lt;/span&gt; {
&lt;span class="lnr"&gt; 21 &lt;/span&gt;                ebase = CKSEG0;
&lt;span class="lnr"&gt; 22 &lt;/span&gt;                &lt;span class="Conditional"&gt;if&lt;/span&gt; (cpu_has_mips_r2)
&lt;span class="lnr"&gt; 23 &lt;/span&gt;                        ebase += (read_c0_ebase() &amp;amp; &lt;span class="Number"&gt;0x3ffff000&lt;/span&gt;);
&lt;span class="lnr"&gt; 24 &lt;/span&gt;        }
&lt;span class="lnr"&gt; 25 &lt;/span&gt;
&lt;span class="lnr"&gt; 26 &lt;/span&gt;        per_cpu_trap_init();
&lt;span class="lnr"&gt; 27 &lt;/span&gt;
&lt;span class="lnr"&gt; 28 &lt;/span&gt;        &lt;span class="Comment"&gt;/*&lt;/span&gt;
&lt;span class="lnr"&gt; 29 &lt;/span&gt;&lt;span class="Comment"&gt;         * Copy the generic exception handlers to their final destination.&lt;/span&gt;
&lt;span class="lnr"&gt; 30 &lt;/span&gt;&lt;span class="Comment"&gt;         * This will be overriden later as suitable for a particular&lt;/span&gt;
&lt;span class="lnr"&gt; 31 &lt;/span&gt;&lt;span class="Comment"&gt;         * configuration.&lt;/span&gt;
&lt;span class="lnr"&gt; 32 &lt;/span&gt;&lt;span class="Comment"&gt;         &lt;/span&gt;&lt;span class="Comment"&gt;*/&lt;/span&gt;
&lt;span class="lnr"&gt; 33 &lt;/span&gt;        set_handler(&lt;span class="Number"&gt;0x180&lt;/span&gt;, &amp;amp;except_vec3_generic, &lt;span class="Number"&gt;0x80&lt;/span&gt;);
&lt;span class="lnr"&gt; 34 &lt;/span&gt;&lt;/pre&gt;line 20~24: It initializes base address of exception vectors (&lt;i&gt;ebase&lt;/i&gt;) to 0x80000000 (&lt;i&gt;CKSEG0&lt;/i&gt;), the power-on default value. MIPSr2 provides an option to adjust &lt;i&gt;ebase&lt;/i&gt; according to VA (bit 29:12) of EBase register.&lt;br /&gt;
&lt;br /&gt;
line 16~19: If VI mode or EIC mode is used, bootmem from offset 0 (goal 0) will be allocated for the handler routeines. &lt;i&gt;__alloc_bootmem&lt;/i&gt; returns virtual address which will also be 0x80000000 (&lt;a href="http://winfred-lu.blogspot.com/2011/03/linux-boot-memory-allocator-mips.html"&gt;an article FYR&lt;/a&gt;). There are 64 handlers in total, and each is of size 0x100 by default. The first 0x200 is also reserved for TLB Refill and Cache Error handlers.&lt;br /&gt;
&lt;br /&gt;
line 26: Cache Error handler and TLB Refill handler are configured in &lt;i&gt;per_cpu_trap_init()&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
line 33: Default exception handler would be located 0x80000180 and of size 128 bytes. &lt;i&gt;set_handler()&lt;/i&gt; copies 128 bytes from the location of &lt;i&gt;except_vec3_generic&lt;/i&gt; to &lt;i&gt;ebase&lt;/i&gt; + 0x180.&lt;br /&gt;
&lt;br /&gt;
Take a look at &lt;i&gt;per_cpu_trap_init()&lt;/i&gt; and &lt;i&gt;except_vec3_generic&lt;/i&gt;.&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt;  1 &lt;/span&gt;&lt;span class="Type"&gt;void&lt;/span&gt; __cpuinit per_cpu_trap_init(&lt;span class="Type"&gt;void&lt;/span&gt;)
&lt;span class="lnr"&gt;  2 &lt;/span&gt;{
&lt;span class="lnr"&gt;  3 &lt;/span&gt;        &lt;span class="Type"&gt;unsigned&lt;/span&gt; &lt;span class="Type"&gt;int&lt;/span&gt; cpu = smp_processor_id();
&lt;span class="lnr"&gt;  x &lt;/span&gt;        ......
&lt;span class="lnr"&gt; 50 &lt;/span&gt;        &lt;span class="Conditional"&gt;if&lt;/span&gt; (cpu_has_veic || cpu_has_vint) {
&lt;span class="lnr"&gt; 51 &lt;/span&gt;                &lt;span class="Type"&gt;unsigned&lt;/span&gt; &lt;span class="Type"&gt;long&lt;/span&gt; sr = set_c0_status(ST0_BEV);
&lt;span class="lnr"&gt; 52 &lt;/span&gt;                write_c0_ebase(ebase);
&lt;span class="lnr"&gt; 53 &lt;/span&gt;                write_c0_status(sr);
&lt;span class="lnr"&gt; 54 &lt;/span&gt;                &lt;span class="Comment"&gt;/*&lt;/span&gt;&lt;span class="Comment"&gt; Setting vector spacing enables EI/VI mode  &lt;/span&gt;&lt;span class="Comment"&gt;*/&lt;/span&gt;
&lt;span class="lnr"&gt; 55 &lt;/span&gt;                change_c0_intctl(&lt;span class="Number"&gt;0x3e0&lt;/span&gt;, VECTORSPACING);
&lt;span class="lnr"&gt; 56 &lt;/span&gt;        }
&lt;span class="lnr"&gt; 57 &lt;/span&gt;        &lt;span class="Conditional"&gt;if&lt;/span&gt; (cpu_has_divec) {
&lt;span class="lnr"&gt; 58 &lt;/span&gt;                &lt;span class="Conditional"&gt;if&lt;/span&gt; (cpu_has_mipsmt) {
&lt;span class="lnr"&gt; 59 &lt;/span&gt;                        &lt;span class="Type"&gt;unsigned&lt;/span&gt; &lt;span class="Type"&gt;int&lt;/span&gt; vpflags = dvpe();
&lt;span class="lnr"&gt; 60 &lt;/span&gt;                        set_c0_cause(CAUSEF_IV);
&lt;span class="lnr"&gt; 61 &lt;/span&gt;                        evpe(vpflags);
&lt;span class="lnr"&gt; 62 &lt;/span&gt;                } &lt;span class="Conditional"&gt;else&lt;/span&gt;
&lt;span class="lnr"&gt; 63 &lt;/span&gt;                        set_c0_cause(CAUSEF_IV);
&lt;span class="lnr"&gt; 64 &lt;/span&gt;        }
&lt;span class="lnr"&gt;  x &lt;/span&gt;        ......
&lt;span class="lnr"&gt; 72 &lt;/span&gt;        &lt;span class="Conditional"&gt;if&lt;/span&gt; (cpu_has_mips_r2) {
&lt;span class="lnr"&gt; 73 &lt;/span&gt;                cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP;
&lt;span class="lnr"&gt; 74 &lt;/span&gt;                cp0_compare_irq = (read_c0_intctl() &amp;gt;&amp;gt; INTCTLB_IPTI) &amp;amp; &lt;span class="Number"&gt;7&lt;/span&gt;;
&lt;span class="lnr"&gt; 75 &lt;/span&gt;                cp0_perfcount_irq = (read_c0_intctl() &amp;gt;&amp;gt; INTCTLB_IPPCI) &amp;amp; &lt;span class="Number"&gt;7&lt;/span&gt;;
&lt;span class="lnr"&gt; 76 &lt;/span&gt;                &lt;span class="Conditional"&gt;if&lt;/span&gt; (cp0_perfcount_irq == cp0_compare_irq)
&lt;span class="lnr"&gt; 77 &lt;/span&gt;                        cp0_perfcount_irq = -&lt;span class="Number"&gt;1&lt;/span&gt;;
&lt;span class="lnr"&gt; 78 &lt;/span&gt;        } &lt;span class="Conditional"&gt;else&lt;/span&gt; {
&lt;span class="lnr"&gt; 79 &lt;/span&gt;                cp0_compare_irq = CP0_LEGACY_COMPARE_IRQ;
&lt;span class="lnr"&gt; 80 &lt;/span&gt;                cp0_compare_irq_shift = cp0_compare_irq;
&lt;span class="lnr"&gt; 81 &lt;/span&gt;                cp0_perfcount_irq = -&lt;span class="Number"&gt;1&lt;/span&gt;;
&lt;span class="lnr"&gt; 82 &lt;/span&gt;        }
&lt;span class="lnr"&gt;  x &lt;/span&gt;        ......
&lt;span class="lnr"&gt; 99 &lt;/span&gt;                cpu_cache_init();
&lt;span class="lnr"&gt;100 &lt;/span&gt;                tlb_init();
&lt;span class="lnr"&gt;  x &lt;/span&gt;        ......
&lt;span class="lnr"&gt;111 &lt;/span&gt;}&lt;/pre&gt;line 50~56: It sets BEV for Status register, configure EBase register with &lt;i&gt;ebase&lt;/i&gt;, and configure VS in IntCtrl register. VS will be &lt;i&gt;VECTORSPACING&lt;/i&gt;(0x100) &amp;lt;&amp;lt; 4 = 8 to get a 256 bytes spacing.&lt;br /&gt;
&lt;br /&gt;
line 57~64: It sets IV in Cause register and special interrupt vector will be used instead.&lt;br /&gt;
&lt;br /&gt;
line 72~82: MIPSr2 provides the flexibility to change the default interrupt numbers for timer interrupt and performance counter interrupt.&lt;br /&gt;
&lt;br /&gt;
line 99: It calls xxx_cache_init() accordingly, &lt;i&gt;r4k_cache_init()&lt;/i&gt; for example, and calls &lt;i&gt;set_uncached_handler()&lt;/i&gt; to build the Cache Error exception handler. It copies the handler &lt;i&gt;except_vec2_generic&lt;/i&gt; to &lt;i&gt;ebase&lt;/i&gt; + 0x100. &lt;i&gt;set_uncached_handler()&lt;/i&gt; is similar to &lt;i&gt;set_handler()&lt;/i&gt;, the only difference is that it uses KSeg1 address of &lt;i&gt;ebase&lt;/i&gt;. &lt;a href="http://lxr.linux.no/#linux+v2.6.38/arch/mips/mm/cex-gen.S#L20"&gt;&lt;i&gt;except_vec2_generic&lt;/i&gt;&lt;/a&gt; turns off KSeg0 caching (sets K0 to 2 in Config register), and jump to &lt;a href="http://lxr.linux.no/#linux+v2.6.38/arch/mips/kernel/traps.c#L1264"&gt;&lt;i&gt;cache_parity_error&lt;/i&gt;&lt;/a&gt; to handle the exception.&lt;br /&gt;
&lt;br /&gt;
line 100: It calls &lt;i&gt;tlb_init()&lt;/i&gt;, then &lt;i&gt;build_tlb_refill_handler()&lt;/i&gt;, then build handlers handling exceptions including TLB refill exception, TLB load exception (&lt;i&gt;handle_tlbl()&lt;/i&gt;), TLB store exception (&lt;i&gt;handle_tlbs()&lt;/i&gt;), and TLB modify read-only area exception (&lt;i&gt;handle_tlbm()&lt;/i&gt;). The &lt;a href="http://lxr.linux.no/#linux+v2.6.38/arch/mips/mm/tlbex.c#L1147"&gt;&lt;i&gt;build_r4000_tlb_refill_handler()&lt;/i&gt;&lt;/a&gt; builds &lt;i&gt;tlb_handler&lt;/i&gt; with correct instructions, copy to &lt;i&gt;final_handler&lt;/i&gt;, fixes relocations, and &lt;a href="http://lxr.linux.no/#linux+v2.6.38/arch/mips/mm/tlbex.c#L1318"&gt;copy&lt;/a&gt; &lt;i&gt;final_handler&lt;/i&gt; to &lt;i&gt;ebase&lt;/i&gt; + 0.&lt;br /&gt;
&lt;br /&gt;
And &lt;i&gt;except_vec3_generic&lt;/i&gt;,&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Function"&gt;NESTED&lt;/span&gt;(&lt;span class="Function"&gt;except_vec3_generic&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;0&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt; 2 &lt;/span&gt;        &lt;span class="PreProc"&gt;.set&lt;/span&gt;    &lt;span class="Keyword"&gt;push&lt;/span&gt;
&lt;span class="lnr"&gt; 3 &lt;/span&gt;        &lt;span class="PreProc"&gt;.set&lt;/span&gt;    &lt;span class="Function"&gt;noat&lt;/span&gt;
&lt;span class="lnr"&gt; 4 &lt;/span&gt;&lt;span class="PreCondit"&gt;#if R5432_CP0_INTERRUPT_WAR&lt;/span&gt;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;        mfc0    k0, CP0_INDEX
&lt;span class="lnr"&gt; 6 &lt;/span&gt;&lt;span class="PreCondit"&gt;#endif&lt;/span&gt;
&lt;span class="lnr"&gt; 7 &lt;/span&gt;        &lt;span class="Keyword"&gt;mfc0&lt;/span&gt;    &lt;span class="Identifier"&gt;k1&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Function"&gt;CP0_CAUSE&lt;/span&gt;
&lt;span class="lnr"&gt; 8 &lt;/span&gt;        &lt;span class="Keyword"&gt;andi&lt;/span&gt;    &lt;span class="Identifier"&gt;k1&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Identifier"&gt;k1&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;0x7c&lt;/span&gt;
&lt;span class="lnr"&gt; 9 &lt;/span&gt;&lt;span class="PreCondit"&gt;#ifdef CONFIG_64BIT&lt;/span&gt;
&lt;span class="lnr"&gt;10 &lt;/span&gt;        dsll    k1, k1, &lt;span class="Number"&gt;1&lt;/span&gt;
&lt;span class="lnr"&gt;11 &lt;/span&gt;&lt;span class="PreCondit"&gt;#endif&lt;/span&gt;
&lt;span class="lnr"&gt;12 &lt;/span&gt;&lt;span class="Function"&gt;PTR_L&lt;/span&gt;   &lt;span class="Identifier"&gt;k0&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Function"&gt;exception_handlers&lt;/span&gt;(&lt;span class="Identifier"&gt;k1&lt;/span&gt;)
&lt;span class="lnr"&gt;13 &lt;/span&gt;        &lt;span class="Keyword"&gt;jr&lt;/span&gt;      &lt;span class="Identifier"&gt;k0&lt;/span&gt;
&lt;span class="lnr"&gt;14 &lt;/span&gt;        &lt;span class="PreProc"&gt;.set&lt;/span&gt;    &lt;span class="Keyword"&gt;pop&lt;/span&gt;
&lt;span class="lnr"&gt;15 &lt;/span&gt;        &lt;span class="Function"&gt;END&lt;/span&gt;(&lt;span class="Function"&gt;except_vec3_generic&lt;/span&gt;)&lt;/pre&gt;line 2: save the current status of flags&lt;br /&gt;
line 3: prevent the assembler from using AT register&lt;br /&gt;
line 7~8: read ExeCode (bit 6:2) from Cause register&lt;br /&gt;
&lt;br /&gt;
line 10: In 64-bit environment, pointers are 8-byte aligned, which is double of size compared to a 4-byte pointer.&lt;br /&gt;
&lt;br /&gt;
line 12: load the handler address from &lt;i&gt;exception_handlers&lt;/i&gt; + k1. &lt;a href="http://lxr.linux.no/#linux+v2.6.38/arch/mips/kernel/traps.c#L1348"&gt;&lt;i&gt;exception_handlers&lt;/i&gt;&lt;/a&gt; is an array of pointers storing address of exception handlers.&lt;br /&gt;
&lt;br /&gt;
line 13: jump to the correct exception handler (according to the ExeCode)&lt;br /&gt;
line 14: restore the previous status of flags&lt;br /&gt;
&lt;br /&gt;
Let us leave &lt;i&gt;per_cpu_trap_init()&lt;/i&gt; and &lt;i&gt;except_vec3_generic()&lt;/i&gt; there and go back to &lt;i&gt;trap_init()&lt;/i&gt;.&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt;  1 &lt;/span&gt;&lt;span class="Type"&gt;void&lt;/span&gt; __init trap_init(&lt;span class="Type"&gt;void&lt;/span&gt;)
&lt;span class="lnr"&gt;  2 &lt;/span&gt;{
&lt;span class="lnr"&gt;  x &lt;/span&gt;        ......
&lt;span class="lnr"&gt; 35 &lt;/span&gt;        &lt;span class="Comment"&gt;/*&lt;/span&gt;
&lt;span class="lnr"&gt; 36 &lt;/span&gt;&lt;span class="Comment"&gt;         * Setup default vectors&lt;/span&gt;
&lt;span class="lnr"&gt; 37 &lt;/span&gt;&lt;span class="Comment"&gt;         &lt;/span&gt;&lt;span class="Comment"&gt;*/&lt;/span&gt;
&lt;span class="lnr"&gt; 38 &lt;/span&gt;        &lt;span class="Repeat"&gt;for&lt;/span&gt; (i = &lt;span class="Number"&gt;0&lt;/span&gt;; i &amp;lt;= &lt;span class="Number"&gt;31&lt;/span&gt;; i++)
&lt;span class="lnr"&gt; 39 &lt;/span&gt;                set_except_vector(i, handle_reserved);
&lt;span class="lnr"&gt; 40 &lt;/span&gt;
&lt;span class="lnr"&gt; 41 &lt;/span&gt;        &lt;span class="Comment"&gt;/*&lt;/span&gt;
&lt;span class="lnr"&gt; 42 &lt;/span&gt;&lt;span class="Comment"&gt;         * Copy the EJTAG debug exception vector handler code to it's final&lt;/span&gt;
&lt;span class="lnr"&gt; 43 &lt;/span&gt;&lt;span class="Comment"&gt;         * destination.&lt;/span&gt;
&lt;span class="lnr"&gt; 44 &lt;/span&gt;&lt;span class="Comment"&gt;         &lt;/span&gt;&lt;span class="Comment"&gt;*/&lt;/span&gt;
&lt;span class="lnr"&gt; 45 &lt;/span&gt;        &lt;span class="Conditional"&gt;if&lt;/span&gt; (cpu_has_ejtag &amp;amp;&amp;amp; board_ejtag_handler_setup)
&lt;span class="lnr"&gt; 46 &lt;/span&gt;                board_ejtag_handler_setup();
&lt;span class="lnr"&gt; 47 &lt;/span&gt;
&lt;span class="lnr"&gt; 48 &lt;/span&gt;        &lt;span class="Comment"&gt;/*&lt;/span&gt;
&lt;span class="lnr"&gt; 49 &lt;/span&gt;&lt;span class="Comment"&gt;         * Only some CPUs have the watch exceptions.&lt;/span&gt;
&lt;span class="lnr"&gt; 50 &lt;/span&gt;&lt;span class="Comment"&gt;         &lt;/span&gt;&lt;span class="Comment"&gt;*/&lt;/span&gt;
&lt;span class="lnr"&gt; 51 &lt;/span&gt;        &lt;span class="Conditional"&gt;if&lt;/span&gt; (cpu_has_watch)
&lt;span class="lnr"&gt; 52 &lt;/span&gt;                set_except_vector(&lt;span class="Number"&gt;23&lt;/span&gt;, handle_watch);
&lt;span class="lnr"&gt; 53 &lt;/span&gt; &lt;/pre&gt;line 38~39: set the 32 exception handlers to &lt;i&gt;handle_reserved()&lt;/i&gt; by default. &lt;a href="http://lxr.linux.no/#linux+v2.6.38/arch/mips/kernel/traps.c#L1351"&gt;&lt;i&gt;set_except_vector()&lt;/i&gt;&lt;/a&gt; will substitute the &lt;i&gt;i&lt;/i&gt;-th entry of &lt;i&gt;exception_handlers[]&lt;/i&gt; with the given address.&lt;br /&gt;
&lt;br /&gt;
line 44~45: configure the EJTAG debug exception handler if needed&lt;br /&gt;
line 51~52: configure watch exception handler to &lt;i&gt;handle_watch()&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;handle_reserved()&lt;/i&gt; and &lt;i&gt;handle_watch()&lt;/i&gt; are both built in arch/mips/kernel/genex.S as the followed:&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt; 1 &lt;/span&gt;        &lt;span class="Function"&gt;BUILD_HANDLER&lt;/span&gt; &lt;span class="Function"&gt;adel&lt;/span&gt; &lt;span class="Function"&gt;ade&lt;/span&gt; &lt;span class="Function"&gt;ade&lt;/span&gt; &lt;span class="Function"&gt;silent&lt;/span&gt;               &lt;span class="Comment"&gt;/* #4  */&lt;/span&gt;
&lt;span class="lnr"&gt; 2 &lt;/span&gt;        &lt;span class="Function"&gt;BUILD_HANDLER&lt;/span&gt; &lt;span class="Function"&gt;ades&lt;/span&gt; &lt;span class="Function"&gt;ade&lt;/span&gt; &lt;span class="Function"&gt;ade&lt;/span&gt; &lt;span class="Function"&gt;silent&lt;/span&gt;               &lt;span class="Comment"&gt;/* #5  */&lt;/span&gt;
&lt;span class="lnr"&gt; 3 &lt;/span&gt;        &lt;span class="Function"&gt;BUILD_HANDLER&lt;/span&gt; &lt;span class="Function"&gt;ibe&lt;/span&gt; &lt;span class="Function"&gt;be&lt;/span&gt; &lt;span class="Keyword"&gt;cli&lt;/span&gt; &lt;span class="Function"&gt;silent&lt;/span&gt;                 &lt;span class="Comment"&gt;/* #6  */&lt;/span&gt;
&lt;span class="lnr"&gt; 4 &lt;/span&gt;        &lt;span class="Function"&gt;BUILD_HANDLER&lt;/span&gt; &lt;span class="Function"&gt;dbe&lt;/span&gt; &lt;span class="Function"&gt;be&lt;/span&gt; &lt;span class="Keyword"&gt;cli&lt;/span&gt; &lt;span class="Function"&gt;silent&lt;/span&gt;                 &lt;span class="Comment"&gt;/* #7  */&lt;/span&gt;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;        &lt;span class="Function"&gt;BUILD_HANDLER&lt;/span&gt; &lt;span class="Function"&gt;bp&lt;/span&gt; &lt;span class="Function"&gt;bp&lt;/span&gt; &lt;span class="Keyword"&gt;sti&lt;/span&gt; &lt;span class="Function"&gt;silent&lt;/span&gt;                  &lt;span class="Comment"&gt;/* #9  */&lt;/span&gt;
&lt;span class="lnr"&gt; 6 &lt;/span&gt;        &lt;span class="Function"&gt;BUILD_HANDLER&lt;/span&gt; &lt;span class="Function"&gt;ri&lt;/span&gt; &lt;span class="Function"&gt;ri&lt;/span&gt; &lt;span class="Keyword"&gt;sti&lt;/span&gt; &lt;span class="Function"&gt;silent&lt;/span&gt;                  &lt;span class="Comment"&gt;/* #10 */&lt;/span&gt;
&lt;span class="lnr"&gt; 7 &lt;/span&gt;        &lt;span class="Function"&gt;BUILD_HANDLER&lt;/span&gt; &lt;span class="Function"&gt;cpu&lt;/span&gt; &lt;span class="Function"&gt;cpu&lt;/span&gt; &lt;span class="Keyword"&gt;sti&lt;/span&gt; &lt;span class="Function"&gt;silent&lt;/span&gt;                &lt;span class="Comment"&gt;/* #11 */&lt;/span&gt;
&lt;span class="lnr"&gt; 8 &lt;/span&gt;        &lt;span class="Function"&gt;BUILD_HANDLER&lt;/span&gt; &lt;span class="Function"&gt;ov&lt;/span&gt; &lt;span class="Function"&gt;ov&lt;/span&gt; &lt;span class="Keyword"&gt;sti&lt;/span&gt; &lt;span class="Function"&gt;silent&lt;/span&gt;                  &lt;span class="Comment"&gt;/* #12 */&lt;/span&gt;
&lt;span class="lnr"&gt; 9 &lt;/span&gt;        &lt;span class="Function"&gt;BUILD_HANDLER&lt;/span&gt; &lt;span class="Function"&gt;tr&lt;/span&gt; &lt;span class="Function"&gt;tr&lt;/span&gt; &lt;span class="Keyword"&gt;sti&lt;/span&gt; &lt;span class="Function"&gt;silent&lt;/span&gt;                  &lt;span class="Comment"&gt;/* #13 */&lt;/span&gt;
&lt;span class="lnr"&gt;10 &lt;/span&gt;        &lt;span class="Function"&gt;BUILD_HANDLER&lt;/span&gt; &lt;span class="Function"&gt;fpe&lt;/span&gt; &lt;span class="Function"&gt;fpe&lt;/span&gt; &lt;span class="Function"&gt;fpe&lt;/span&gt; &lt;span class="Function"&gt;silent&lt;/span&gt;                &lt;span class="Comment"&gt;/* #15 */&lt;/span&gt;
&lt;span class="lnr"&gt;11 &lt;/span&gt;        &lt;span class="Function"&gt;BUILD_HANDLER&lt;/span&gt; &lt;span class="Function"&gt;mdmx&lt;/span&gt; &lt;span class="Function"&gt;mdmx&lt;/span&gt; &lt;span class="Keyword"&gt;sti&lt;/span&gt; &lt;span class="Function"&gt;silent&lt;/span&gt;              &lt;span class="Comment"&gt;/* #22 */&lt;/span&gt;
&lt;span class="lnr"&gt;12 &lt;/span&gt;&lt;span class="PreCondit"&gt;#ifdef  CONFIG_HARDWARE_WATCHPOINTS&lt;/span&gt;
&lt;span class="lnr"&gt;13 &lt;/span&gt;        &lt;span class="Comment"&gt;/*&lt;/span&gt;
&lt;span class="lnr"&gt;14 &lt;/span&gt;&lt;span class="Comment"&gt;         * For watch, interrupts will be enabled after the watch&lt;/span&gt;
&lt;span class="lnr"&gt;15 &lt;/span&gt;&lt;span class="Comment"&gt;         * registers are read.&lt;/span&gt;
&lt;span class="lnr"&gt;16 &lt;/span&gt;&lt;span class="Comment"&gt;         &lt;/span&gt;&lt;span class="Comment"&gt;*/&lt;/span&gt;
&lt;span class="lnr"&gt;17 &lt;/span&gt;        &lt;span class="Function"&gt;BUILD_HANDLER&lt;/span&gt; &lt;span class="Function"&gt;watch&lt;/span&gt; &lt;span class="Function"&gt;watch&lt;/span&gt; &lt;span class="Keyword"&gt;cli&lt;/span&gt; &lt;span class="Function"&gt;silent&lt;/span&gt;            &lt;span class="Comment"&gt;/* #23 */&lt;/span&gt;
&lt;span class="lnr"&gt;18 &lt;/span&gt;&lt;span class="PreCondit"&gt;#else&lt;/span&gt;
&lt;span class="lnr"&gt;19 &lt;/span&gt;        &lt;span class="Function"&gt;BUILD_HANDLER&lt;/span&gt; &lt;span class="Function"&gt;watch&lt;/span&gt; &lt;span class="Function"&gt;watch&lt;/span&gt; &lt;span class="Keyword"&gt;sti&lt;/span&gt; &lt;span class="Function"&gt;verbose&lt;/span&gt;           &lt;span class="Comment"&gt;/* #23 */&lt;/span&gt;
&lt;span class="lnr"&gt;20 &lt;/span&gt;&lt;span class="PreCondit"&gt;#endif&lt;/span&gt;
&lt;span class="lnr"&gt;21 &lt;/span&gt;        &lt;span class="Function"&gt;BUILD_HANDLER&lt;/span&gt; &lt;span class="Function"&gt;mcheck&lt;/span&gt; &lt;span class="Function"&gt;mcheck&lt;/span&gt; &lt;span class="Keyword"&gt;cli&lt;/span&gt; &lt;span class="Function"&gt;verbose&lt;/span&gt;         &lt;span class="Comment"&gt;/* #24 */&lt;/span&gt;
&lt;span class="lnr"&gt;22 &lt;/span&gt;        &lt;span class="Function"&gt;BUILD_HANDLER&lt;/span&gt; &lt;span class="Function"&gt;mt&lt;/span&gt; &lt;span class="Function"&gt;mt&lt;/span&gt; &lt;span class="Keyword"&gt;sti&lt;/span&gt; &lt;span class="Function"&gt;silent&lt;/span&gt;                  &lt;span class="Comment"&gt;/* #25 */&lt;/span&gt;
&lt;span class="lnr"&gt;23 &lt;/span&gt;        &lt;span class="Function"&gt;BUILD_HANDLER&lt;/span&gt; &lt;span class="Function"&gt;dsp&lt;/span&gt; &lt;span class="Function"&gt;dsp&lt;/span&gt; &lt;span class="Keyword"&gt;sti&lt;/span&gt; &lt;span class="Function"&gt;silent&lt;/span&gt;                &lt;span class="Comment"&gt;/* #26 */&lt;/span&gt;
&lt;span class="lnr"&gt;24 &lt;/span&gt;        &lt;span class="Function"&gt;BUILD_HANDLER&lt;/span&gt; &lt;span class="Function"&gt;reserved&lt;/span&gt; &lt;span class="Function"&gt;reserved&lt;/span&gt; &lt;span class="Keyword"&gt;sti&lt;/span&gt; &lt;span class="Function"&gt;verbose&lt;/span&gt;     &lt;span class="Comment"&gt;/* others */&lt;/span&gt; &lt;/pre&gt;Each call to &lt;i&gt;BUILD_HANDLER&lt;/i&gt; will build two functions, &lt;i&gt;handle_\exception&lt;/i&gt; and &lt;i&gt;handle_\exception_int&lt;/i&gt;. Thus, you may look the symbol table for &lt;i&gt;handle_adel()&lt;/i&gt;, &lt;i&gt;handle_adel_int()&lt;/i&gt;, &lt;i&gt;handle_ades()&lt;/i&gt;, &lt;i&gt;handle_ades_int()&lt;/i&gt;, and so on.&lt;br /&gt;
&lt;br /&gt;
How do these handlers get prepared and handle exceptions?&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt; 1 &lt;/span&gt;        &lt;span class="Macro"&gt;.macro&lt;/span&gt;  &lt;span class="Function"&gt;__BUILD_HANDLER&lt;/span&gt; &lt;span class="Function"&gt;exception&lt;/span&gt; &lt;span class="Function"&gt;handler&lt;/span&gt; &lt;span class="Function"&gt;clear&lt;/span&gt; &lt;span class="Function"&gt;verbose&lt;/span&gt; &lt;span class="Keyword"&gt;ext&lt;/span&gt;
&lt;span class="lnr"&gt; 2 &lt;/span&gt;        &lt;span class="PreProc"&gt;.align&lt;/span&gt;  &lt;span class="Constant"&gt;5&lt;/span&gt;
&lt;span class="lnr"&gt; 3 &lt;/span&gt;        &lt;span class="Function"&gt;NESTED&lt;/span&gt;(&lt;span class="Function"&gt;handle_\exception&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Function"&gt;PT_SIZE&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt; 4 &lt;/span&gt;        &lt;span class="PreProc"&gt;.set&lt;/span&gt;    &lt;span class="Function"&gt;noat&lt;/span&gt;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;        &lt;span class="Function"&gt;SAVE_ALL&lt;/span&gt;
&lt;span class="lnr"&gt; 6 &lt;/span&gt;        &lt;span class="Function"&gt;FEXPORT&lt;/span&gt;(&lt;span class="Function"&gt;handle_\exception\ext&lt;/span&gt;)
&lt;span class="lnr"&gt; 7 &lt;/span&gt;        &lt;span class="Function"&gt;__BUILD_clear_\clear&lt;/span&gt;
&lt;span class="lnr"&gt; 8 &lt;/span&gt;        &lt;span class="PreProc"&gt;.set&lt;/span&gt;    &lt;span class="Identifier"&gt;at&lt;/span&gt;
&lt;span class="lnr"&gt; 9 &lt;/span&gt;        &lt;span class="Function"&gt;__BUILD_\verbose&lt;/span&gt; \&lt;span class="Function"&gt;exception&lt;/span&gt;
&lt;span class="lnr"&gt;10 &lt;/span&gt;        &lt;span class="Keyword"&gt;move&lt;/span&gt;    &lt;span class="Identifier"&gt;a0&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Identifier"&gt;sp&lt;/span&gt;
&lt;span class="lnr"&gt;11 &lt;/span&gt;        &lt;span class="Function"&gt;PTR_LA&lt;/span&gt;  &lt;span class="Identifier"&gt;ra&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Function"&gt;ret_from_exception&lt;/span&gt;
&lt;span class="lnr"&gt;12 &lt;/span&gt;        &lt;span class="Keyword"&gt;j&lt;/span&gt;       &lt;span class="Function"&gt;do_\handler&lt;/span&gt;
&lt;span class="lnr"&gt;13 &lt;/span&gt;        &lt;span class="Function"&gt;END&lt;/span&gt;(&lt;span class="Function"&gt;handle_\exception&lt;/span&gt;)
&lt;span class="lnr"&gt;14 &lt;/span&gt;        &lt;span class="Operator"&gt;.&lt;/span&gt;endm
&lt;span class="lnr"&gt;15 &lt;/span&gt;
&lt;span class="lnr"&gt;16 &lt;/span&gt;        &lt;span class="Macro"&gt;.macro&lt;/span&gt;  &lt;span class="Function"&gt;BUILD_HANDLER&lt;/span&gt; &lt;span class="Function"&gt;exception&lt;/span&gt; &lt;span class="Function"&gt;handler&lt;/span&gt; &lt;span class="Function"&gt;clear&lt;/span&gt; &lt;span class="Function"&gt;verbose&lt;/span&gt;
&lt;span class="lnr"&gt;17 &lt;/span&gt;        &lt;span class="Function"&gt;__BUILD_HANDLER&lt;/span&gt; \&lt;span class="Function"&gt;exception&lt;/span&gt; \&lt;span class="Function"&gt;handler&lt;/span&gt; \&lt;span class="Function"&gt;clear&lt;/span&gt; \&lt;span class="Function"&gt;verbose&lt;/span&gt; &lt;span class="Function"&gt;_int&lt;/span&gt;
&lt;span class="lnr"&gt;18 &lt;/span&gt;        &lt;span class="Operator"&gt;.&lt;/span&gt;endm &lt;/pre&gt;line 16~18: &lt;i&gt;BUILD_HANDLER&lt;/i&gt; invokes &lt;i&gt;__BUILD_HANDLER&lt;/i&gt; to build handlers&lt;br /&gt;
&lt;br /&gt;
line 3: Frame size of &lt;i&gt;handle_\exception()&lt;/i&gt; is &lt;i&gt;PT_SIZE&lt;/i&gt;, which is &lt;a href="http://lxr.linux.no/#linux+v2.6.38/arch/mips/kernel/asm-offsets.c#L72"&gt;automatically generated&lt;/a&gt; by Kbuild according to &lt;i&gt;sizeof(struct pt_regs)&lt;/i&gt;. &lt;i&gt;pt_regs&lt;/i&gt; defines how registers are stored in stack during the exception.&lt;br /&gt;
&lt;br /&gt;
line 4: tell the assembler no to use AT register because we will&lt;br /&gt;
&lt;br /&gt;
line 5: save some CP0 registers and all the general purpose registers by calling &lt;i&gt;SAVE_SOME&lt;/i&gt;, &lt;i&gt;SAVE_AT&lt;/i&gt;, &lt;i&gt;SAVE_TEMP&lt;/i&gt;, and &lt;i&gt;SAVE_STATIC&lt;/i&gt;. The registers will be stored onto stack in order as defined in &lt;i&gt;pt_regs&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
line 6: export the &lt;i&gt;handle_\exception_int()&lt;/i&gt; symbol. &lt;i&gt;handle_\exception()&lt;/i&gt; and &lt;i&gt;handle_\exception_int()&lt;/i&gt; share contents below this line.&lt;br /&gt;
&lt;br /&gt;
line 7: could be &lt;a href="http://lxr.linux.no/#linux+v2.6.38/arch/mips/include/asm/stackframe.h#L482"&gt;CLI&lt;/a&gt;, &lt;a href="http://lxr.linux.no/#linux+v2.6.38/arch/mips/include/asm/stackframe.h#L517"&gt;STI&lt;/a&gt;, &lt;a href="http://lxr.linux.no/#linux+v2.6.38/arch/mips/kernel/genex.S#L387"&gt;fpe&lt;/a&gt;, or &lt;a href="http://lxr.linux.no/#linux+v2.6.38/arch/mips/kernel/genex.S#L400"&gt;ade&lt;/a&gt;&lt;br /&gt;
line 8: The assembler is free to use AT because we've done our saving job.&lt;br /&gt;
line 9: &lt;a href="http://lxr.linux.no/#linux+v2.6.38/arch/mips/kernel/genex.S#L409"&gt;print&lt;/a&gt; the information of &lt;i&gt;EPC&lt;/i&gt; if verbose is set&lt;br /&gt;
&lt;br /&gt;
line 10~11: prepare to jump &lt;i&gt;do_\handler()&lt;/i&gt;. The first argument is &lt;i&gt;sp&lt;/i&gt;, the pointer to &lt;i&gt;pt_regs&lt;/i&gt;. The return address is the address of &lt;i&gt;ret_from_exception()&lt;/i&gt;, the function called when exception handling is done. &lt;i&gt;ret_from_exception()&lt;/i&gt; will restore registers back, and return to the original address (discussed later).&lt;br /&gt;
&lt;br /&gt;
line 12: call the exception handling function &lt;i&gt;do_\handler()&lt;/i&gt;, such as &lt;i&gt;do_ade()&lt;/i&gt;, &lt;i&gt;do_be()&lt;/i&gt;, &lt;i&gt;do_ri&lt;/i&gt;, and so on.&lt;br /&gt;
&lt;br /&gt;
Okey, let's go back to &lt;i&gt;trap_init()&lt;/i&gt; again.&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt;  1 &lt;/span&gt;&lt;span class="Type"&gt;void&lt;/span&gt; __init trap_init(&lt;span class="Type"&gt;void&lt;/span&gt;)
&lt;span class="lnr"&gt;  2 &lt;/span&gt;{
&lt;span class="lnr"&gt;  x &lt;/span&gt;        ......
&lt;span class="lnr"&gt; 54 &lt;/span&gt;        &lt;span class="Comment"&gt;/*&lt;/span&gt;
&lt;span class="lnr"&gt; 55 &lt;/span&gt;&lt;span class="Comment"&gt;         * Initialise interrupt handlers&lt;/span&gt;
&lt;span class="lnr"&gt; 56 &lt;/span&gt;&lt;span class="Comment"&gt;         &lt;/span&gt;&lt;span class="Comment"&gt;*/&lt;/span&gt;
&lt;span class="lnr"&gt; 57 &lt;/span&gt;        &lt;span class="Conditional"&gt;if&lt;/span&gt; (cpu_has_veic || cpu_has_vint) {
&lt;span class="lnr"&gt; 58 &lt;/span&gt;                &lt;span class="Type"&gt;int&lt;/span&gt; nvec = cpu_has_veic ? &lt;span class="Number"&gt;64&lt;/span&gt; : &lt;span class="Number"&gt;8&lt;/span&gt;;
&lt;span class="lnr"&gt; 59 &lt;/span&gt;                &lt;span class="Repeat"&gt;for&lt;/span&gt; (i = &lt;span class="Number"&gt;0&lt;/span&gt;; i &amp;lt; nvec; i++)
&lt;span class="lnr"&gt; 60 &lt;/span&gt;                        set_vi_handler(i, &lt;span class="Constant"&gt;NULL&lt;/span&gt;);
&lt;span class="lnr"&gt; 61 &lt;/span&gt;        }
&lt;span class="lnr"&gt; 62 &lt;/span&gt;        &lt;span class="Conditional"&gt;else&lt;/span&gt; &lt;span class="Conditional"&gt;if&lt;/span&gt; (cpu_has_divec)
&lt;span class="lnr"&gt; 63 &lt;/span&gt;                set_handler(&lt;span class="Number"&gt;0x200&lt;/span&gt;, &amp;amp;except_vec4, &lt;span class="Number"&gt;0x8&lt;/span&gt;);
&lt;span class="lnr"&gt; 64 &lt;/span&gt;
&lt;span class="lnr"&gt; 65 &lt;/span&gt;        &lt;span class="Comment"&gt;/*&lt;/span&gt;
&lt;span class="lnr"&gt; 66 &lt;/span&gt;&lt;span class="Comment"&gt;         * Some CPUs can enable/disable for cache parity detection, but does&lt;/span&gt;
&lt;span class="lnr"&gt; 67 &lt;/span&gt;&lt;span class="Comment"&gt;         * it different ways.&lt;/span&gt;
&lt;span class="lnr"&gt; 68 &lt;/span&gt;&lt;span class="Comment"&gt;         &lt;/span&gt;&lt;span class="Comment"&gt;*/&lt;/span&gt;
&lt;span class="lnr"&gt; 69 &lt;/span&gt;        parity_protection_init();
&lt;span class="lnr"&gt; 70 &lt;/span&gt;
&lt;span class="lnr"&gt; 71 &lt;/span&gt;        &lt;span class="Comment"&gt;/*&lt;/span&gt;
&lt;span class="lnr"&gt; 72 &lt;/span&gt;&lt;span class="Comment"&gt;         * The Data Bus Errors / Instruction Bus Errors are signaled&lt;/span&gt;
&lt;span class="lnr"&gt; 73 &lt;/span&gt;&lt;span class="Comment"&gt;         * by external hardware.  Therefore these two exceptions&lt;/span&gt;
&lt;span class="lnr"&gt; 74 &lt;/span&gt;&lt;span class="Comment"&gt;         * may have board specific handlers.&lt;/span&gt;
&lt;span class="lnr"&gt; 75 &lt;/span&gt;&lt;span class="Comment"&gt;         &lt;/span&gt;&lt;span class="Comment"&gt;*/&lt;/span&gt;
&lt;span class="lnr"&gt; 76 &lt;/span&gt;        &lt;span class="Conditional"&gt;if&lt;/span&gt; (board_be_init)
&lt;span class="lnr"&gt; 77 &lt;/span&gt;                board_be_init();
&lt;span class="lnr"&gt; 78 &lt;/span&gt;&lt;/pre&gt;line 57~61: in VI or EIC mode, set interrupt handler to &lt;i&gt;NULL&lt;/i&gt; by default. BSP providers need to configure every interrupt handler accordingly. It calls &lt;i&gt;set_vi_srs_handler()&lt;/i&gt; and &lt;a href="http://lxr.linux.no/#linux+v2.6.38/arch/mips/kernel/traps.c#L1443"&gt;copies&lt;/a&gt; the given handler to &lt;i&gt;ebase&lt;/i&gt; + 0x200 + n*&lt;i&gt;VECTORSPACING&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
line 62~63: configure &lt;i&gt;except_vec4&lt;/i&gt; as the default special interrupt handler&lt;br /&gt;
line 69: enable cache parity dectection if it is implemented. (ErrCtrl register)&lt;br /&gt;
line 76~77: configure the Data/Instruction Bus Error exception handler if supported&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt;  1 &lt;/span&gt;&lt;span class="Type"&gt;void&lt;/span&gt; __init trap_init(&lt;span class="Type"&gt;void&lt;/span&gt;)
&lt;span class="lnr"&gt;  2 &lt;/span&gt;{
&lt;span class="lnr"&gt;  x &lt;/span&gt;        ......
&lt;span class="lnr"&gt; 79 &lt;/span&gt;        set_except_vector(&lt;span class="Number"&gt;0&lt;/span&gt;, rollback ? rollback_handle_int : handle_int);
&lt;span class="lnr"&gt; 80 &lt;/span&gt;        set_except_vector(&lt;span class="Number"&gt;1&lt;/span&gt;, handle_tlbm);
&lt;span class="lnr"&gt; 81 &lt;/span&gt;        set_except_vector(&lt;span class="Number"&gt;2&lt;/span&gt;, handle_tlbl);
&lt;span class="lnr"&gt; 82 &lt;/span&gt;        set_except_vector(&lt;span class="Number"&gt;3&lt;/span&gt;, handle_tlbs);
&lt;span class="lnr"&gt; 83 &lt;/span&gt;
&lt;span class="lnr"&gt; 84 &lt;/span&gt;        set_except_vector(&lt;span class="Number"&gt;4&lt;/span&gt;, handle_adel);
&lt;span class="lnr"&gt; 85 &lt;/span&gt;        set_except_vector(&lt;span class="Number"&gt;5&lt;/span&gt;, handle_ades);
&lt;span class="lnr"&gt; 86 &lt;/span&gt;
&lt;span class="lnr"&gt; 87 &lt;/span&gt;        set_except_vector(&lt;span class="Number"&gt;6&lt;/span&gt;, handle_ibe);
&lt;span class="lnr"&gt; 88 &lt;/span&gt;        set_except_vector(&lt;span class="Number"&gt;7&lt;/span&gt;, handle_dbe);
&lt;span class="lnr"&gt; 89 &lt;/span&gt;
&lt;span class="lnr"&gt; 90 &lt;/span&gt;        set_except_vector(&lt;span class="Number"&gt;8&lt;/span&gt;, handle_sys);
&lt;span class="lnr"&gt; 91 &lt;/span&gt;        set_except_vector(&lt;span class="Number"&gt;9&lt;/span&gt;, handle_bp);
&lt;span class="lnr"&gt; 92 &lt;/span&gt;        set_except_vector(&lt;span class="Number"&gt;10&lt;/span&gt;, rdhwr_noopt ? handle_ri :
&lt;span class="lnr"&gt; 93 &lt;/span&gt;                          (cpu_has_vtag_icache ?
&lt;span class="lnr"&gt; 94 &lt;/span&gt;                           handle_ri_rdhwr_vivt : handle_ri_rdhwr));
&lt;span class="lnr"&gt; 95 &lt;/span&gt;        set_except_vector(&lt;span class="Number"&gt;11&lt;/span&gt;, handle_cpu);
&lt;span class="lnr"&gt; 96 &lt;/span&gt;        set_except_vector(&lt;span class="Number"&gt;12&lt;/span&gt;, handle_ov);
&lt;span class="lnr"&gt; 97 &lt;/span&gt;        set_except_vector(&lt;span class="Number"&gt;13&lt;/span&gt;, handle_tr);
&lt;span class="lnr"&gt;  x &lt;/span&gt;        ......
&lt;span class="lnr"&gt;114 &lt;/span&gt;        &lt;span class="Conditional"&gt;if&lt;/span&gt; (board_nmi_handler_setup)
&lt;span class="lnr"&gt;115 &lt;/span&gt;                board_nmi_handler_setup();
&lt;span class="lnr"&gt;116 &lt;/span&gt;
&lt;span class="lnr"&gt;117 &lt;/span&gt;        &lt;span class="Conditional"&gt;if&lt;/span&gt; (cpu_has_fpu &amp;amp;&amp;amp; !cpu_has_nofpuex)
&lt;span class="lnr"&gt;118 &lt;/span&gt;                set_except_vector(&lt;span class="Number"&gt;15&lt;/span&gt;, handle_fpe);
&lt;span class="lnr"&gt;119 &lt;/span&gt;
&lt;span class="lnr"&gt;120 &lt;/span&gt;        set_except_vector(&lt;span class="Number"&gt;22&lt;/span&gt;, handle_mdmx);
&lt;span class="lnr"&gt;121 &lt;/span&gt;
&lt;span class="lnr"&gt;122 &lt;/span&gt;        &lt;span class="Conditional"&gt;if&lt;/span&gt; (cpu_has_mcheck)
&lt;span class="lnr"&gt;123 &lt;/span&gt;                set_except_vector(&lt;span class="Number"&gt;24&lt;/span&gt;, handle_mcheck);
&lt;span class="lnr"&gt;124 &lt;/span&gt;
&lt;span class="lnr"&gt;125 &lt;/span&gt;        &lt;span class="Conditional"&gt;if&lt;/span&gt; (cpu_has_mipsmt)
&lt;span class="lnr"&gt;126 &lt;/span&gt;                set_except_vector(&lt;span class="Number"&gt;25&lt;/span&gt;, handle_mt);
&lt;span class="lnr"&gt;127 &lt;/span&gt;
&lt;span class="lnr"&gt;128 &lt;/span&gt;        set_except_vector(&lt;span class="Number"&gt;26&lt;/span&gt;, handle_dsp);
&lt;span class="lnr"&gt;129 &lt;/span&gt;&lt;/pre&gt;line 79~128: configure exception handler seperately. 0~26 are exception codes (ExeCode of Cause register), the meaning of their value could be referenced to MIPS user manual. For example, 0 means that it is an interrupt, 1 means that TLB modify to read-only page exception.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt;  1 &lt;/span&gt;&lt;span class="Type"&gt;void&lt;/span&gt; __init trap_init(&lt;span class="Type"&gt;void&lt;/span&gt;)
&lt;span class="lnr"&gt;  2 &lt;/span&gt;{
&lt;span class="lnr"&gt;  x &lt;/span&gt;        ......
&lt;span class="lnr"&gt;130 &lt;/span&gt;        &lt;span class="Conditional"&gt;if&lt;/span&gt; (cpu_has_vce)
&lt;span class="lnr"&gt;131 &lt;/span&gt;                &lt;span class="Comment"&gt;/*&lt;/span&gt;&lt;span class="Comment"&gt; Special exception: R4[04]00 uses also the divec space. &lt;/span&gt;&lt;span class="Comment"&gt;*/&lt;/span&gt;
&lt;span class="lnr"&gt;132 &lt;/span&gt;                memcpy((&lt;span class="Type"&gt;void&lt;/span&gt; *)(ebase + &lt;span class="Number"&gt;0x180&lt;/span&gt;), &amp;amp;except_vec3_r4000, &lt;span class="Number"&gt;0x100&lt;/span&gt;);
&lt;span class="lnr"&gt;133 &lt;/span&gt;        &lt;span class="Conditional"&gt;else&lt;/span&gt; &lt;span class="Conditional"&gt;if&lt;/span&gt; (cpu_has_4kex)
&lt;span class="lnr"&gt;134 &lt;/span&gt;                memcpy((&lt;span class="Type"&gt;void&lt;/span&gt; *)(ebase + &lt;span class="Number"&gt;0x180&lt;/span&gt;), &amp;amp;except_vec3_generic, &lt;span class="Number"&gt;0x80&lt;/span&gt;);
&lt;span class="lnr"&gt;135 &lt;/span&gt;        &lt;span class="Conditional"&gt;else&lt;/span&gt;
&lt;span class="lnr"&gt;136 &lt;/span&gt;                memcpy((&lt;span class="Type"&gt;void&lt;/span&gt; *)(ebase + &lt;span class="Number"&gt;0x080&lt;/span&gt;), &amp;amp;except_vec3_generic, &lt;span class="Number"&gt;0x80&lt;/span&gt;);
&lt;span class="lnr"&gt;137 &lt;/span&gt;
&lt;span class="lnr"&gt;138 &lt;/span&gt;        local_flush_icache_range(ebase, ebase + &lt;span class="Number"&gt;0x400&lt;/span&gt;);
&lt;span class="lnr"&gt;139 &lt;/span&gt;        flush_tlb_handlers();
&lt;span class="lnr"&gt;140 &lt;/span&gt;
&lt;span class="lnr"&gt;141 &lt;/span&gt;        sort_extable(__start___dbe_table, __stop___dbe_table);
&lt;span class="lnr"&gt;142 &lt;/span&gt;
&lt;span class="lnr"&gt;143 &lt;/span&gt;        cu2_notifier(default_cu2_call, &lt;span class="Number"&gt;0x80000000&lt;/span&gt;);    &lt;span class="Comment"&gt;/*&lt;/span&gt;&lt;span class="Comment"&gt; Run last  &lt;/span&gt;&lt;span class="Comment"&gt;*/&lt;/span&gt;
&lt;span class="lnr"&gt;144 &lt;/span&gt;}&lt;/pre&gt;line 130~136: Here we don't support virtual coherence conflict exception, and copy &lt;i&gt;except_vec3_generic&lt;/i&gt; to the address of default exception vector again.&lt;br /&gt;
&lt;br /&gt;
line 138~139: flush ICache for address in the range of exception handlers&lt;br /&gt;
line 141: sort the exception table for data bus error&lt;br /&gt;
&lt;br /&gt;
Interrupt is a special type of the exceptions; it comes from outside the CPU core. When a exception with ExeCode equal to 0, it is an interrupt. Let's see how interrupts are dealt with:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Function"&gt;NESTED&lt;/span&gt;(&lt;span class="Function"&gt;handle_int&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Function"&gt;PT_SIZE&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt; 2 &lt;/span&gt;&lt;span class="Operator"&gt;+--&lt;/span&gt; &lt;span class="Constant"&gt;31&lt;/span&gt; &lt;span class="Function"&gt;lines&lt;/span&gt;: &lt;span class="Comment"&gt;#ifdef CONFIG_TRACE_IRQFLAGS------------------&lt;/span&gt;
&lt;span class="lnr"&gt; 3 &lt;/span&gt;        &lt;span class="Function"&gt;SAVE_ALL&lt;/span&gt;
&lt;span class="lnr"&gt; 4 &lt;/span&gt;        &lt;span class="Keyword"&gt;CLI&lt;/span&gt;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;        &lt;span class="Function"&gt;TRACE_IRQS_OFF&lt;/span&gt;
&lt;span class="lnr"&gt; 6 &lt;/span&gt;
&lt;span class="lnr"&gt; 7 &lt;/span&gt;        &lt;span class="Function"&gt;LONG_L&lt;/span&gt;  &lt;span class="Identifier"&gt;s0&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Function"&gt;TI_REGS&lt;/span&gt;(&lt;span class="Constant"&gt;$28&lt;/span&gt;)
&lt;span class="lnr"&gt; 8 &lt;/span&gt;        &lt;span class="Function"&gt;LONG_S&lt;/span&gt;  &lt;span class="Identifier"&gt;sp&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Function"&gt;TI_REGS&lt;/span&gt;(&lt;span class="Constant"&gt;$28&lt;/span&gt;)
&lt;span class="lnr"&gt; 9 &lt;/span&gt;        &lt;span class="Function"&gt;PTR_LA&lt;/span&gt;  &lt;span class="Identifier"&gt;ra&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Function"&gt;ret_from_irq&lt;/span&gt;
&lt;span class="lnr"&gt;10 &lt;/span&gt;        &lt;span class="Keyword"&gt;j&lt;/span&gt;       &lt;span class="Function"&gt;plat_irq_dispatch&lt;/span&gt;
&lt;span class="lnr"&gt;11 &lt;/span&gt;        &lt;span class="Function"&gt;END&lt;/span&gt;(&lt;span class="Function"&gt;handle_int&lt;/span&gt;) &lt;/pre&gt;line 2, 5: trace IRQ stuff, we are not going to discuss it here.&lt;br /&gt;
line 3: save some CP0 registers and all the general purpose registers to stack&lt;br /&gt;
line 4: CLI to clear the interrupts&lt;br /&gt;
&lt;br /&gt;
line 7: save the information of &lt;i&gt;pt_regs&lt;/i&gt; pointer to current &lt;i&gt;thread_info&lt;/i&gt; to &lt;i&gt;s0&lt;/i&gt;&lt;br /&gt;
line 8: load the &lt;i&gt;pt_regs&lt;/i&gt; pointer with the stack pointer (where we saved all registers)&lt;br /&gt;
&lt;br /&gt;
line 9: set return address to &lt;i&gt;ret_from_irq&lt;/i&gt; instead, so that handler will return to &lt;i&gt;ret_from_irq&lt;/i&gt; after the interrupt&lt;br /&gt;
&lt;br /&gt;
line 10: jump to the platform dependent interrupt handling routine&lt;br /&gt;
&lt;br /&gt;
As you may see, &lt;i&gt;handle_int&lt;/i&gt; is similar to &lt;i&gt;handle_\exception&lt;/i&gt; with the differences:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;&lt;i&gt;handle_int&lt;/i&gt; needs to CLI, while &lt;i&gt;handle_\exception&lt;/i&gt; may use CLI, STI, fpe, or ade.&lt;/li&gt;
&lt;li&gt;the return address of &lt;i&gt;handle_int&lt;/i&gt; is &lt;i&gt;ret_from_irq&lt;/i&gt;; the return address of &lt;i&gt;handle_\exception&lt;/i&gt; is &lt;i&gt;ret_from_exception&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;&lt;i&gt;handle_int&lt;/i&gt; will jump to &lt;i&gt;plat_irq_dispatch&lt;/i&gt;, &lt;i&gt;handle_\exception&lt;/i&gt; will jump to &lt;i&gt;do_\handler&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;&lt;i&gt;do_\handler&lt;/i&gt; has an argument, a pointer to &lt;i&gt;pt_regs&lt;/i&gt;. &lt;i&gt;handle_\exception&lt;/i&gt; copies stack pointer to &lt;i&gt;a0&lt;/i&gt; for the usage.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;plat_irq_dispatch&lt;/i&gt; has no argument, and the pointer to &lt;i&gt;pt_regs&lt;/i&gt; will be in current &lt;i&gt;thread_info&lt;/i&gt;. So &lt;i&gt;handle_int&lt;/i&gt; has to save the current &lt;i&gt;pt_regs&lt;/i&gt; to &lt;i&gt;s0&lt;/i&gt; before updating it with stack pointer&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
Interrupts and handling are often different between platforms. Developers have to implement &lt;i&gt;plat_irq_dispatch()&lt;/i&gt; accordingly. A common handler is provded in arch/mips/mipssim/sim_int.c. It finds the first pending interrupt number and calls &lt;i&gt;do_IRQ(no.)&lt;/i&gt; to handle it.&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt; 1 &lt;/span&gt;asmlinkage &lt;span class="Type"&gt;void&lt;/span&gt; plat_irq_dispatch(&lt;span class="Type"&gt;void&lt;/span&gt;)
&lt;span class="lnr"&gt; 2 &lt;/span&gt;{
&lt;span class="lnr"&gt; 3 &lt;/span&gt;        &lt;span class="Type"&gt;unsigned&lt;/span&gt; &lt;span class="Type"&gt;int&lt;/span&gt; pending = read_c0_cause() &amp;amp; read_c0_status() &amp;amp; ST0_IM;
&lt;span class="lnr"&gt; 4 &lt;/span&gt;        &lt;span class="Type"&gt;int&lt;/span&gt; irq;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;
&lt;span class="lnr"&gt; 6 &lt;/span&gt;        irq = irq_ffs(pending);
&lt;span class="lnr"&gt; 7 &lt;/span&gt;
&lt;span class="lnr"&gt; 8 &lt;/span&gt;        &lt;span class="Conditional"&gt;if&lt;/span&gt; (irq &amp;gt; &lt;span class="Number"&gt;0&lt;/span&gt;)
&lt;span class="lnr"&gt; 9 &lt;/span&gt;                do_IRQ(MIPS_CPU_IRQ_BASE + irq);
&lt;span class="lnr"&gt;10 &lt;/span&gt;        &lt;span class="Conditional"&gt;else&lt;/span&gt;
&lt;span class="lnr"&gt;11 &lt;/span&gt;                spurious_interrupt();
&lt;span class="lnr"&gt;12 &lt;/span&gt;} &lt;/pre&gt;line 3: read pending interrupts from Cause register and masked by IM7-0 of Status register&lt;br /&gt;
&lt;br /&gt;
line 6: find the first bit set in pendings. This is an example of handling compatible interrupts, first bit is the highest priority interrupt.&lt;br /&gt;
&lt;br /&gt;
line 8~9: &lt;i&gt;do_IRQ()&lt;/i&gt; to handle the interrupt&lt;br /&gt;
line 10~11: It is a spurious interrupt (should not happen).&lt;br /&gt;
&lt;br /&gt;
And when exception or interrupt has been handle, it invokes &lt;i&gt;ret_from_exception&lt;/i&gt; or &lt;i&gt;ret_from_irq&lt;/i&gt; to return to the original executions.&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="PreCondit"&gt;#ifndef CONFIG_PREEMPT&lt;/span&gt;
&lt;span class="lnr"&gt; 2 &lt;/span&gt;&lt;span class="Macro"&gt;#define resume_kernel   restore_all&lt;/span&gt;
&lt;span class="lnr"&gt; 3 &lt;/span&gt;&lt;span class="PreCondit"&gt;#else&lt;/span&gt;
&lt;span class="lnr"&gt; 4 &lt;/span&gt;&lt;span class="Macro"&gt;#define __ret_from_irq  ret_from_exception&lt;/span&gt;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;&lt;span class="PreCondit"&gt;#endif&lt;/span&gt;
&lt;span class="lnr"&gt; 6 &lt;/span&gt;
&lt;span class="lnr"&gt; 7 &lt;/span&gt;        &lt;span class="PreProc"&gt;.text&lt;/span&gt;
&lt;span class="lnr"&gt; 8 &lt;/span&gt;        &lt;span class="PreProc"&gt;.align&lt;/span&gt;  &lt;span class="Constant"&gt;5&lt;/span&gt;
&lt;span class="lnr"&gt; 9 &lt;/span&gt;&lt;span class="PreCondit"&gt;#ifndef CONFIG_PREEMPT&lt;/span&gt;
&lt;span class="lnr"&gt;10 &lt;/span&gt;FEXPORT(ret_from_exception)
&lt;span class="lnr"&gt;11 &lt;/span&gt;        &lt;span class="Function"&gt;local_irq_disable&lt;/span&gt;                       &lt;span class="Comment"&gt;# preempt stop&lt;/span&gt;
&lt;span class="lnr"&gt;12 &lt;/span&gt;        &lt;span class="Keyword"&gt;b&lt;/span&gt;       &lt;span class="Function"&gt;__ret_from_irq&lt;/span&gt;
&lt;span class="lnr"&gt;13 &lt;/span&gt;&lt;span class="PreCondit"&gt;#endif&lt;/span&gt;
&lt;span class="lnr"&gt;14 &lt;/span&gt;&lt;span class="Function"&gt;FEXPORT&lt;/span&gt;(&lt;span class="Function"&gt;ret_from_irq&lt;/span&gt;)
&lt;span class="lnr"&gt;15 &lt;/span&gt;        &lt;span class="Function"&gt;LONG_S&lt;/span&gt;  &lt;span class="Identifier"&gt;s0&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Function"&gt;TI_REGS&lt;/span&gt;(&lt;span class="Constant"&gt;$28&lt;/span&gt;)
&lt;span class="lnr"&gt;16 &lt;/span&gt;&lt;span class="Function"&gt;FEXPORT&lt;/span&gt;(&lt;span class="Function"&gt;__ret_from_irq&lt;/span&gt;)
&lt;span class="lnr"&gt;17 &lt;/span&gt;        &lt;span class="Function"&gt;LONG_L&lt;/span&gt;  &lt;span class="Identifier"&gt;t0&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Function"&gt;PT_STATUS&lt;/span&gt;(&lt;span class="Identifier"&gt;sp&lt;/span&gt;)               &lt;span class="Comment"&gt;# returning to kernel mode?&lt;/span&gt;
&lt;span class="lnr"&gt;18 &lt;/span&gt;        &lt;span class="Keyword"&gt;andi&lt;/span&gt;    &lt;span class="Identifier"&gt;t0&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Identifier"&gt;t0&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Function"&gt;KU_USER&lt;/span&gt;
&lt;span class="lnr"&gt;19 &lt;/span&gt;        &lt;span class="Keyword"&gt;beqz&lt;/span&gt;    &lt;span class="Identifier"&gt;t0&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Function"&gt;resume_kernel&lt;/span&gt;
&lt;span class="lnr"&gt;20 &lt;/span&gt;
&lt;span class="lnr"&gt;21 &lt;/span&gt;&lt;span class="Function"&gt;resume_userspace&lt;/span&gt;:
&lt;span class="lnr"&gt;22 &lt;/span&gt;        &lt;span class="Function"&gt;local_irq_disable&lt;/span&gt;               &lt;span class="Comment"&gt;# make sure we dont miss an&lt;/span&gt;
&lt;span class="lnr"&gt;23 &lt;/span&gt;                                        &lt;span class="Comment"&gt;# interrupt setting need_resched&lt;/span&gt;
&lt;span class="lnr"&gt;24 &lt;/span&gt;                                        &lt;span class="Comment"&gt;# between sampling and return&lt;/span&gt;
&lt;span class="lnr"&gt;25 &lt;/span&gt;        &lt;span class="Function"&gt;LONG_L&lt;/span&gt;  &lt;span class="Identifier"&gt;a2&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Function"&gt;TI_FLAGS&lt;/span&gt;(&lt;span class="Constant"&gt;$28&lt;/span&gt;)       &lt;span class="Comment"&gt;# current-&amp;gt;work&lt;/span&gt;
&lt;span class="lnr"&gt;26 &lt;/span&gt;        &lt;span class="Keyword"&gt;andi&lt;/span&gt;    &lt;span class="Identifier"&gt;t0&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Identifier"&gt;a2&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Function"&gt;_TIF_WORK_MASK&lt;/span&gt;  &lt;span class="Comment"&gt;# (ignoring syscall_trace)&lt;/span&gt;
&lt;span class="lnr"&gt;27 &lt;/span&gt;        &lt;span class="Keyword"&gt;bnez&lt;/span&gt;    &lt;span class="Identifier"&gt;t0&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Function"&gt;work_pending&lt;/span&gt;
&lt;span class="lnr"&gt;28 &lt;/span&gt;        &lt;span class="Keyword"&gt;j&lt;/span&gt;       &lt;span class="Function"&gt;restore_all&lt;/span&gt; &lt;/pre&gt;line 10,14: &lt;i&gt;ret_from_exception&lt;/i&gt; and &lt;i&gt;ret_from_irq&lt;/i&gt; share the context because they are similar.&lt;br /&gt;
line 15: &lt;i&gt;ret_from_irq&lt;/i&gt; has to restore back the pointer of &lt;i&gt;pt_regs&lt;/i&gt; of &lt;i&gt;thread_info&lt;/i&gt; stored in &lt;i&gt;s0&lt;/i&gt; previously.&lt;br /&gt;
line 17~18: read UM of Status register and see if it is in kernel mode&lt;br /&gt;
line 19, 1~3: if in kernel mode, jump to &lt;i&gt;resume_kernel&lt;/i&gt; (it actually calls &lt;i&gt;restore_all&lt;/i&gt;)&lt;br /&gt;
line 21~28: if in user mode, also call &lt;i&gt;restore_all&lt;/i&gt; after finishing pending workings&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;restore_all&lt;/i&gt; will call  RESTORE_TEMP, RESTORE_AT, RESTORE_STATIC, RESTORE_SOME, and &lt;a href="http://lxr.linux.no/linux+*/arch/mips/include/asm/stackframe.h#L449"&gt;&lt;i&gt;RESTORE_SP_AND_RET&lt;/i&gt;&lt;/a&gt;. &lt;i&gt;RESTORE_SP_AND_RET&lt;/i&gt; will execute &lt;i&gt;eret&lt;/i&gt; instruction finally, it clears EXL of Status register and returns to the address stored in EPC, then original execution continues.&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Morgan-Kaufmann-Computer-Architecture-Design/dp/1558604103"&gt;Dominic Sweetman, See MIPS Run&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;MIPS Software User Manual&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.cs.pitt.edu/%7Edon/coe1502/current/Unit4a/Unit4a.html"&gt;Exception and Interrupt handling in the MIPS architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://tldp.org/LDP/tlk/dd/interrupts.html"&gt;TLDP, David A Rusling, Interrupts and Interrupt Handling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://lxr.linux.no/linux"&gt;the Linux Cross Reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://git.linux-mips.org/?p=linux.git;a=summary"&gt;Linux MIPS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1626185782516232162-5995259804292484465?l=winfred-lu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://winfred-lu.blogspot.com/feeds/5995259804292484465/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1626185782516232162&amp;postID=5995259804292484465' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/5995259804292484465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/5995259804292484465'/><link rel='alternate' type='text/html' href='http://winfred-lu.blogspot.com/2011/04/mips-exceptions-initialization-and.html' title='MIPS Exceptions Initialization and Handling on Linux'/><author><name>Winfred</name><uri>http://www.blogger.com/profile/15649970719010644298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm2.static.flickr.com/1104/569054989_83809a02b2_m.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-XIjitojvfxY/TZxNngRE7pI/AAAAAAAAAWE/lA7-CIukh64/s72-c/2011-04-06_192418.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1626185782516232162.post-3429191432276402688</id><published>2011-03-04T00:10:00.000-08:00</published><updated>2011-04-06T04:16:52.072-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mips'/><category scheme='http://www.blogger.com/atom/ns#' term='bootmem'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='kernel'/><category scheme='http://www.blogger.com/atom/ns#' term='memory'/><title type='text'>Learning the Linux Boot Memory Allocator (MIPS)</title><content type='html'>Do you ever look at the report of 'cat /proc/meminfo' and wonder why the reported &lt;i&gt;MemTotal&lt;/i&gt; is not equal to the amount of memory you have for the system? The followed is an example report from one of my systems. It shows the total memory is 60860kB (59.4MB) from line 2:&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt;1 &lt;/span&gt;# cat /proc/meminfo
&lt;span class="lnr"&gt;2 &lt;/span&gt;MemTotal:          60860 kB
&lt;span class="lnr"&gt;3 &lt;/span&gt;MemFree:           47448 kB
&lt;span class="lnr"&gt;4 &lt;/span&gt;Buffers:               0 kB
&lt;span class="lnr"&gt;5 &lt;/span&gt;Cached:             7180 kB
&lt;span class="lnr"&gt;6 &lt;/span&gt;SwapCached:            0 kB
&lt;span class="lnr"&gt;7 &lt;/span&gt;... &lt;/pre&gt;&lt;br /&gt;
which is different from the amount of memory that bootloader gave to kernel, 64MB.&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt;1 &lt;/span&gt;...
&lt;span class="lnr"&gt;2 &lt;/span&gt;## Transferring control to Linux (at address 800042f0) ...
&lt;span class="lnr"&gt;3 &lt;/span&gt;## Giving linux memsize in MB, 64 &lt;/pre&gt;&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
The total physical memory is 64MB (0x4000000) according to the kernel log line 4. And the memory available (line 20) is 59176k because 6360k bytes is reserved. As we know that available = total - reserved. (59176k = 65536k - 6360k).&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt; 1 &lt;/span&gt;# dmesg
&lt;span class="lnr"&gt; 2 &lt;/span&gt;...
&lt;span class="lnr"&gt; 3 &lt;/span&gt;Determined physical RAM map:
&lt;span class="lnr"&gt; 4 &lt;/span&gt; memory: 04000000 @ 00000000 (usable)
&lt;span class="lnr"&gt; 5 &lt;/span&gt;Initrd not found or empty - disabling initrd
&lt;span class="lnr"&gt; 6 &lt;/span&gt;Zone PFN ranges:
&lt;span class="lnr"&gt; 7 &lt;/span&gt;  Normal   0x00000000 -&amp;gt; 0x00004000
&lt;span class="lnr"&gt; 8 &lt;/span&gt;Movable zone start PFN for each node
&lt;span class="lnr"&gt; 9 &lt;/span&gt;early_node_map[1] active PFN ranges
&lt;span class="lnr"&gt;10 &lt;/span&gt;    0: 0x00000000 -&amp;gt; 0x00004000
&lt;span class="lnr"&gt;11 &lt;/span&gt;Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 16256
&lt;span class="lnr"&gt;12 &lt;/span&gt;Kernel command line: console=ttyS1,57600n8 root=/dev/ram0 rootfstype=squashfs
&lt;span class="lnr"&gt;13 &lt;/span&gt;PID hash table entries: 256 (order: -2, 1024 bytes)
&lt;span class="lnr"&gt;14 &lt;/span&gt;Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
&lt;span class="lnr"&gt;15 &lt;/span&gt;Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
&lt;span class="lnr"&gt;16 &lt;/span&gt;Primary instruction cache 64kB, VIPT, 4-way, linesize 32 bytes.
&lt;span class="lnr"&gt;17 &lt;/span&gt;Primary data cache 32kB, 4-way, PIPT, no aliases, linesize 32 bytes
&lt;span class="lnr"&gt;18 &lt;/span&gt;Writing ErrCtl register=00000000
&lt;span class="lnr"&gt;19 &lt;/span&gt;Readback ErrCtl register=00000000
&lt;span class="lnr"&gt;20 &lt;/span&gt;Memory: 59176k/65536k available (2905k kernel code, 6360k reserved, 980k data, 1684k init, 0k highmem)
&lt;span class="lnr"&gt;21 &lt;/span&gt;...
&lt;span class="lnr"&gt;22 &lt;/span&gt;Freeing unused kernel memory: 1684k freed
&lt;span class="lnr"&gt;23 &lt;/span&gt;... &lt;/pre&gt;&lt;br /&gt;
However, you may notice that &lt;i&gt;MemTotal&lt;/i&gt; and the available memory are not equal. It is because kernel can free memory reserved for initialization during booting, if the memory is not going to used again. Developers mark those codes with a specific attribute, and link them into the &lt;i&gt;.init&lt;/i&gt; section. Kernel will release the memory by invoking &lt;a href="http://lxr.linux.no/#linux+v2.6.36/arch/mips/mm/init.c#L458"&gt;free_initmem()&lt;/a&gt; when initial bootup is done.&lt;br /&gt;
&lt;br /&gt;
Thus, MemTotal = total - reserved + .init&lt;br /&gt;
In the example, 60860k = 65536k - 6360k + 1684k&lt;br /&gt;
&lt;br /&gt;
The question is what does kernel reserved those memory for? Most of reserved memory is used to store kernel image. Take a look to the information read from vmlinux as the followed, sections with number within 0 and 13 are required, including the well known text, data, and bss sections. We can conclude that more than 0x5a7b90 bytes of memory could be used. The minimum unit of reserved memory is 1 page (4K bytes by default). Hense 0x5a7b90 will be 4K aligned instead, which is 0x5a8000.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt; 1 &lt;/span&gt;$ readelf -S vmlinux
&lt;span class="lnr"&gt; 2 &lt;/span&gt;There are 19 section headers, starting at offset 0x576694:
&lt;span class="lnr"&gt; 3 &lt;/span&gt;
&lt;span class="lnr"&gt; 4 &lt;/span&gt;Section Headers:
&lt;span class="lnr"&gt; 5 &lt;/span&gt;  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
&lt;span class="lnr"&gt; 6 &lt;/span&gt;  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
&lt;span class="lnr"&gt; 7 &lt;/span&gt;  [ 1] .text             PROGBITS        80000000 002000 2d66f8 00  AX  0   0 2048
&lt;span class="lnr"&gt; 8 &lt;/span&gt;  [ 2] __ex_table        PROGBITS        802d6700 2d8700 001b20 00   A  0   0  4
&lt;span class="lnr"&gt; 9 &lt;/span&gt;  [ 3] .rodata           PROGBITS        802d9000 2db000 0b09fc 00   A  0   0 32
&lt;span class="lnr"&gt;10 &lt;/span&gt;  [ 4] __ksymtab         PROGBITS        803899fc 38b9fc 004d20 00   A  0   0  4
&lt;span class="lnr"&gt;11 &lt;/span&gt;  [ 5] __ksymtab_gpl     PROGBITS        8038e71c 39071c 0022c8 00   A  0   0  4
&lt;span class="lnr"&gt;12 &lt;/span&gt;  [ 6] __ksymtab_strings PROGBITS        803909e4 3929e4 00f55e 00   A  0   0  1
&lt;span class="lnr"&gt;13 &lt;/span&gt;  [ 7] __param           PROGBITS        8039ff44 3a1f44 0010bc 00   A  0   0  4
&lt;span class="lnr"&gt;14 &lt;/span&gt;  [ 8] .data             PROGBITS        803a2000 3a4000 0299c0 00  WA  0   0 8192
&lt;span class="lnr"&gt;15 &lt;/span&gt;  [ 9] .data..shared_ali PROGBITS        803cb9c0 3cd9c0 000080 00  WA  0   0 32
&lt;span class="lnr"&gt;16 &lt;/span&gt;  [10] .init.text        PROGBITS        803cc000 3ce000 024270 00  AX  0   0  4
&lt;span class="lnr"&gt;17 &lt;/span&gt;  [11] .init.data        PROGBITS        803f0270 3f2270 17f6f2 00  WA  0   0  8
&lt;span class="lnr"&gt;18 &lt;/span&gt;  [12] .exit.text        PROGBITS        8056f964 571964 0015d8 00  AX  0   0  4
&lt;span class="lnr"&gt;19 &lt;/span&gt;  [13] .bss              NOBITS          80571000 572f3c 036b90 00  WA  0   0 4096
&lt;span class="lnr"&gt;20 &lt;/span&gt;  [14] .mdebug.abi32     PROGBITS        805a7b90 572f3c 000000 00      0   0  1
&lt;span class="lnr"&gt;21 &lt;/span&gt;  [15] .comment          PROGBITS        00000000 572f3c 0036a2 00      0   0  1
&lt;span class="lnr"&gt;22 &lt;/span&gt;  [16] .shstrtab         STRTAB          00000000 5765de 0000b3 00      0   0  1
&lt;span class="lnr"&gt;23 &lt;/span&gt;  [17] .symtab           SYMTAB          00000000 57698c 063290 10     18 18308  4
&lt;span class="lnr"&gt;24 &lt;/span&gt;  [18] .strtab           STRTAB          00000000 5d9c1c 077ce3 00      0   0  1
&lt;span class="lnr"&gt;25 &lt;/span&gt;Key to Flags:
&lt;span class="lnr"&gt;26 &lt;/span&gt;  W (write), A (alloc), X (execute), M (merge), S (strings)
&lt;span class="lnr"&gt;27 &lt;/span&gt;  I (info), L (link order), G (group), x (unknown)
&lt;span class="lnr"&gt;28 &lt;/span&gt;  O (extra OS processing required) o (OS specific), p (processor specific) &lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
To dig deeper, let's turn the bootmem debugging on by adding "bootmem_debug=1" to the kernel command line. We focus on MIPS in this example, and implementation of bootmem allocator for other architectures could be slightly different. But the basic idea is the same. Bootmem allocator uses a bitmap structure representing the use of memory. It allows us to allocate memory by simply setting or clearing the corresponding bit, before getting the zone allocator ready.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Comment"&gt;# dmesg&lt;/span&gt;
&lt;span class="lnr"&gt; 2 &lt;/span&gt;...
&lt;span class="lnr"&gt; 3 &lt;/span&gt;Determined physical RAM map:
&lt;span class="lnr"&gt; 4 &lt;/span&gt; memory: 04000000 @ 00000000 (usable)
&lt;span class="lnr"&gt; 5 &lt;/span&gt;bootmem::init_bootmem_core nid=0 start=0 map=5a8 end=4000 mapsize=800
&lt;span class="lnr"&gt; 6 &lt;/span&gt;bootmem::mark_bootmem_node nid=0 start=5a8 end=4000 reserve=0 flags=0
&lt;span class="lnr"&gt; 7 &lt;/span&gt;bootmem::__free nid=0 start=5a8 end=4000
&lt;span class="lnr"&gt; 8 &lt;/span&gt;bootmem::mark_bootmem_node nid=0 start=5a8 end=5a9 reserve=1 flags=0
&lt;span class="lnr"&gt; 9 &lt;/span&gt;bootmem::__reserve nid=0 start=5a8 end=5a9 flags=0
&lt;span class="lnr"&gt;10 &lt;/span&gt;Initrd not found or empty - disabling initrd
&lt;span class="lnr"&gt;11 &lt;/span&gt;Zone PFN ranges:
&lt;span class="lnr"&gt;12 &lt;/span&gt;  Normal   0x00000000 -&amp;gt; 0x00004000
&lt;span class="lnr"&gt;13 &lt;/span&gt;Movable zone start PFN for each node
&lt;span class="lnr"&gt;14 &lt;/span&gt;early_node_map[1] active PFN ranges
&lt;span class="lnr"&gt;15 &lt;/span&gt;    0: 0x00000000 -&amp;gt; 0x00004000
&lt;span class="lnr"&gt;16 &lt;/span&gt;bootmem::alloc_bootmem_core nid=0 size=80000 [128 pages] align=20 goal=1000000 limit=0
&lt;span class="lnr"&gt;17 &lt;/span&gt;bootmem::__reserve nid=0 start=1000 end=1080 flags=1
&lt;span class="lnr"&gt;18 &lt;/span&gt;bootmem::alloc_bootmem_core nid=0 size=8 [1 pages] align=20 goal=1000000 limit=0
&lt;span class="lnr"&gt;19 &lt;/span&gt;bootmem::__reserve nid=0 start=1080 end=1081 flags=1
&lt;span class="lnr"&gt;20 &lt;/span&gt;bootmem::alloc_bootmem_core nid=0 size=200 [1 pages] align=20 goal=1000000 limit=0
&lt;span class="lnr"&gt;21 &lt;/span&gt;bootmem::__reserve nid=0 start=1081 end=1081 flags=1
&lt;span class="lnr"&gt;22 &lt;/span&gt;bootmem::alloc_bootmem_core nid=0 size=1c [1 pages] align=20 goal=1000000 limit=0
&lt;span class="lnr"&gt;23 &lt;/span&gt;bootmem::__reserve nid=0 start=1081 end=1081 flags=1
&lt;span class="lnr"&gt;24 &lt;/span&gt;bootmem::alloc_bootmem_core nid=0 size=49 [1 pages] align=20 goal=1000000 limit=0
&lt;span class="lnr"&gt;25 &lt;/span&gt;bootmem::__reserve nid=0 start=1081 end=1081 flags=1
&lt;span class="lnr"&gt;26 &lt;/span&gt;bootmem::alloc_bootmem_core nid=0 size=49 [1 pages] align=20 goal=1000000 limit=0
&lt;span class="lnr"&gt;27 &lt;/span&gt;bootmem::__reserve nid=0 start=1081 end=1081 flags=1
&lt;span class="lnr"&gt;28 &lt;/span&gt;Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 16256
&lt;span class="lnr"&gt;29 &lt;/span&gt;Kernel command line: console=ttyS1,57600n8 root=/dev/ram0 rootfstype=squashfs bootmem_debug=1
&lt;span class="lnr"&gt;30 &lt;/span&gt;bootmem::alloc_bootmem_core nid=0 size=400 [1 pages] align=20 goal=1000000 limit=0
&lt;span class="lnr"&gt;31 &lt;/span&gt;bootmem::__reserve nid=0 start=1081 end=1081 flags=1
&lt;span class="lnr"&gt;32 &lt;/span&gt;PID hash table entries: 256 (order: -2, 1024 bytes)
&lt;span class="lnr"&gt;33 &lt;/span&gt;bootmem::alloc_bootmem_core nid=0 size=8000 [8 pages] align=20 goal=1000000 limit=0
&lt;span class="lnr"&gt;34 &lt;/span&gt;bootmem::__reserve nid=0 start=1081 end=1089 flags=1
&lt;span class="lnr"&gt;35 &lt;/span&gt;Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
&lt;span class="lnr"&gt;36 &lt;/span&gt;bootmem::alloc_bootmem_core nid=0 size=4000 [4 pages] align=20 goal=1000000 limit=0
&lt;span class="lnr"&gt;37 &lt;/span&gt;bootmem::__reserve nid=0 start=1089 end=108d flags=1
&lt;span class="lnr"&gt;38 &lt;/span&gt;Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
&lt;span class="lnr"&gt;39 &lt;/span&gt;Primary instruction cache 64kB, VIPT, 4-way, linesize 32 bytes.
&lt;span class="lnr"&gt;40 &lt;/span&gt;Primary data cache 32kB, 4-way, PIPT, no aliases, linesize 32 bytes
&lt;span class="lnr"&gt;41 &lt;/span&gt;Writing ErrCtl register=00000000
&lt;span class="lnr"&gt;42 &lt;/span&gt;Readback ErrCtl register=00000000
&lt;span class="lnr"&gt;43 &lt;/span&gt;bootmem::free_all_bootmem_core nid=0 start=0 end=4000 aligned=1
&lt;span class="lnr"&gt;44 &lt;/span&gt;bootmem::free_all_bootmem_core nid=0 released=39cb
&lt;span class="lnr"&gt;45 &lt;/span&gt;Memory: 59176k/65536k available (2905k kernel code, 6360k reserved, 980k data, 1684k init, 0k highmem)
&lt;span class="lnr"&gt;46 &lt;/span&gt;...
&lt;span class="lnr"&gt;47 &lt;/span&gt;Freeing unused kernel memory: 1684k freed
&lt;span class="lnr"&gt;48 &lt;/span&gt;...  &lt;/pre&gt;&lt;br /&gt;
&lt;a href="http://lxr.linux.no/#linux+v2.6.36/arch/mips/kernel/setup.c#L254"&gt;bootmem_init()&lt;/a&gt; initialises the bootmem allocator and setup initrd related data if needed. It calls init_bootmem_node() and calls &lt;a href="http://lxr.linux.no/#linux+v2.6.36/mm/bootmem.c#L96"&gt;init_bootmem_core()&lt;/a&gt;, and reserves all the pages intaially. In function bootmem_init(), the variable &lt;i&gt;mapstart&lt;/i&gt; comes from the symbol &lt;a href="http://lxr.linux.no/#linux+v2.6.36/arch/mips/kernel/vmlinux.lds.S#L118"&gt;&lt;i&gt;_end&lt;/i&gt;&lt;/a&gt;. It is the first free PFN (page frame number) and states the location of bootmem bitmap.&lt;br /&gt;
&lt;br /&gt;
the _end from symbol table:&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt; 1 &lt;/span&gt;$ tail System.map
&lt;span class="lnr"&gt; 2 &lt;/span&gt;805a7ab0 b sit_net_id
&lt;span class="lnr"&gt; 3 &lt;/span&gt;805a7ac0 b ip6_tnl_net_id
&lt;span class="lnr"&gt; 4 &lt;/span&gt;805a7ad0 B br_should_route_hook
&lt;span class="lnr"&gt; 5 &lt;/span&gt;805a7ae0 b br_fdb_cache
&lt;span class="lnr"&gt; 6 &lt;/span&gt;805a7ae4 b fdb_salt
&lt;span class="lnr"&gt; 7 &lt;/span&gt;805a7af0 b br_mac_zero_aligned
&lt;span class="lnr"&gt; 8 &lt;/span&gt;805a7b00 B vlan_net_id
&lt;span class="lnr"&gt; 9 &lt;/span&gt;805a7b04 b vlan_group_hash
&lt;span class="lnr"&gt;10 &lt;/span&gt;805a7b90 A __bss_stop
&lt;span class="lnr"&gt;11 &lt;/span&gt;805a7b90 A _end &lt;/pre&gt;&lt;br /&gt;
Line 5 of kernel log tells us that: it iniailises node ID 0 (This is an UMA system and only 1 node exists.), PFN range is from 0 to 0x3999, and the bootmem bitmap is located at PFN 0x5a8 and of size 0x800 bytes. 64MB memory needs pages of number 64M/4K = 16K = 0x4000, and 16KB pages needs bootmem bitmap of size 16K/8 = 2K = 0x800 bytes.&lt;br /&gt;
&lt;br /&gt;
Line 6~7: bootmem_init() then calls &lt;a href="http://lxr.linux.no/#linux+v2.6.36/mm/bootmem.c#L459"&gt;free_bootmem()&lt;/a&gt; and calls mark_bootmem(). It marks pages after the location of kernel image usable, and the ranage is within PFN 0x5a8 and 0x3999.&lt;br /&gt;
&lt;br /&gt;
Line 8~9: bootmem_init() then calls &lt;a href="http://lxr.linux.no/#linux+v2.6.36/mm/bootmem.c#L512"&gt;reserve_bootmem()&lt;/a&gt; and calls mark_bootmem(). It reserve memory for bootmem bitmap. The bootmap size is 0x800 bytes, less than 1 page, so PFN 0x5a8 is enough.&lt;br /&gt;
&lt;br /&gt;
Line 11~15: kernel initialises paging system, calls &lt;a href="http://lxr.linux.no/#linux+v2.6.36/mm/page_alloc.c#L4607"&gt;free_area_init_nodes()&lt;/a&gt; to initialise all &lt;i&gt;pg_data_t&lt;/i&gt; and zone data, and prints information of all zones, movable zones, and early node map.&lt;br /&gt;
&lt;br /&gt;
Line 16~17: free_area_init_nodes() calls &lt;a href="http://lxr.linux.no/#linux+v2.6.36/mm/page_alloc.c#L4181"&gt;free_area_init_node()&lt;/a&gt; for each node. It calculate total pages of this node, and calls &lt;a href="http://lxr.linux.no/#linux+v2.6.36/mm/page_alloc.c#L4140"&gt;alloc_node_mem_map()&lt;/a&gt; to allocate memory for memory map. The size of one page structure is 32 bytes, and we need 0x4000 pages totally. So the allocation size would be 0x32 * 0x4000 = 0x80000 bytes, which is 128 pages (0x80000 / 0x1000). The goal 0x1000000 means that it allocates memory in normal zone. It skips the first 16MB of DMA addresses. Because the address 0x1000000 is PFN 0x1000, &lt;a href="http://lxr.linux.no/#linux+v2.6.36/mm/bootmem.c#L552"&gt;alloc_bootmem_core()&lt;/a&gt; will allocate pages starting from PFN 0x1000.&lt;br /&gt;
&lt;br /&gt;
Line 18~21: free_area_init_node() calls &lt;a href="http://lxr.linux.no/#linux+v2.6.36/mm/page_alloc.c#L4050"&gt;free_area_init_core()&lt;/a&gt; to built the memory map, and initialise freelists and buddy bitmaps of every zone in the node. It calls setup_usemap() to allocate bootmem for &lt;i&gt;pageblock_flags.&lt;/i&gt; The usemap size is 0x4000 / 0x400 * 3, rounded up 32, then / 8 = 8 bytes (line 18). During zone data initialization, free_area_init_core() also calls zone_wait_table_init() to initialise wait queue hash table. Size of &lt;i&gt;wait_queue_head_t&lt;/i&gt; is 8 bytes and number of wait queue is 64, so the allocation size would be 8 * 0x40 = 0x200 bytes (line 20).&lt;br /&gt;
&lt;br /&gt;
Line 21: Why would the start and end PFN be the same? Line 19 reserves less than 1 page, and alloc_bootmem_core() will attemp to use a free fragment of the last allocated page. It calculates allocation size each time called, and sums up the information in &lt;i&gt;bdata-&amp;gt;last_end_off&lt;/i&gt;. When &lt;i&gt;last_end_off&lt;/i&gt; is less than a page, a free fragment exists. Next time allocating bootmem, it will try to use the fragment if its size is enough. We may see that line 21, 23, 25, 27, and 31 shared the same page.&lt;br /&gt;
&lt;br /&gt;
Line 22~23: Kernel tries to allocate bootmem for resource in resource_init(). The size of resource structure is 28 (0x1c) bytes.&lt;br /&gt;
&lt;br /&gt;
Line 24~27: Kernel tries to allocate bootmem for saved_command_line and static_command_line in setup_command_line(), and both of them are of length 72 (0x49) bytes. The command line is also printed in line 29.&lt;br /&gt;
&lt;br /&gt;
Line 28: Number of pages in this zone is 16384 (0x4000), and 128 of them are used for memory map. Therefore, the present_pages is 16384 - 128 = 16256.&lt;br /&gt;
&lt;br /&gt;
Line 30~32: Kernel tries to allocate bootmem for PID hash table in pidhash_init(). pid_hash is 4 bytes, and the table is 256 * 4 = 1024 (0x400) bytes.&lt;br /&gt;
&lt;br /&gt;
Line 33~38: Kernel tries to allocate bootmem for Dentry cache and Inode cache hash table in vfs_caches_init_early(). 1 hash list structure is 4 bytes. 8192 Dentry cache hash entries woul be 8192 * 4 = 0x8000 bytes. And 4096 Inode cache hash entries would be 0x4000 bytes.&lt;br /&gt;
&lt;br /&gt;
Line 43~44: When the memory sub system is ready, it calls free_all_bootmem() that calls &lt;a href="http://lxr.linux.no/#linux+v2.6.36/mm/bootmem.c#L220"&gt;free_all_bootmem_core()&lt;/a&gt; for each bootmem bitmap to release all free pages to the buddy allocator. It examines the node_bootmem_map for all pages in the node (PFN 0 ~ 0x4000), calls &lt;a href="http://lxr.linux.no/#linux+v2.6.36/mm/page_alloc.c#L689"&gt;__free_pages_bootmem()&lt;/a&gt; to release free either 32 pages or 1 page each time (depending on vec is all 1s or not). Free pages include PFN 0x5a9 ~ 0xfff and 0x108d ~ 0x3fff, and the total number of them is 0x39ca. And we can check the size of reserved memory: (0x4000 - 0x39ca) * 4096 = 6360K bytes. After freeing those pages, the pages storing bootmem bitmap can also be freed. It is 1 page in this example. Thus, the total number of released pages is 0x39cb (line 44).&lt;br /&gt;
&lt;br /&gt;
Line 47: When kernel completes initial bootup and ready to start user-mode stuff, it calls free_initmem() to free &lt;i&gt;.init&lt;/i&gt; section between symbol &lt;i&gt;__init_begin&lt;/i&gt; and &lt;i&gt;__init_end.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;In conclusion,&lt;/b&gt;&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;available memory = total - reserved&lt;/li&gt;
&lt;li&gt;MemTotal = total - reserved + .init&lt;/li&gt;
&lt;li&gt;Bootmem allocator uses a simple bitmap representing the use of memory.&lt;/li&gt;
&lt;li&gt;Reserved memory is mainly used to store kernel image.&lt;/li&gt;
&lt;li&gt;The rest of reserved memory is for memory map, various hash tables, and some miscellaneous data.&lt;/li&gt;
&lt;li&gt;After the memory sub system and zone allocator get ready, it will release the memory used for bootmem bitmap (bootmem retires).&lt;/li&gt;
&lt;li&gt;When initial bootup is done, it will release the &lt;i&gt;.init&lt;/i&gt; section that will never be used again.&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://kneuro.net/linux-mm/index.php?file=bootmem.html"&gt;Joe Knapka, Linux Virtual Memory Subsystem: The Boot-time Allocator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.phptr.com/content/images/0131453483/downloads/gorman_book.pdf"&gt;Mel Gorman, Understanding the Linux Virtual Memory Manager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.kernel.org/doc/gorman/html/understand/understand008.html"&gt;Mel Gorman, Boot Memory Allocator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://linux-mm.org/LinuxMMDocumentation"&gt;Linux MM Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://lxr.linux.no/linux"&gt;the Linux Cross Reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://git.linux-mips.org/?p=linux.git;a=summary"&gt;Linux MIPS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1626185782516232162-3429191432276402688?l=winfred-lu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://winfred-lu.blogspot.com/feeds/3429191432276402688/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1626185782516232162&amp;postID=3429191432276402688' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/3429191432276402688'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/3429191432276402688'/><link rel='alternate' type='text/html' href='http://winfred-lu.blogspot.com/2011/03/linux-boot-memory-allocator-mips.html' title='Learning the Linux Boot Memory Allocator (MIPS)'/><author><name>Winfred</name><uri>http://www.blogger.com/profile/15649970719010644298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm2.static.flickr.com/1104/569054989_83809a02b2_m.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1626185782516232162.post-5155342910644164336</id><published>2010-06-21T02:29:00.000-07:00</published><updated>2011-03-15T19:54:28.182-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mips'/><category scheme='http://www.blogger.com/atom/ns#' term='gnu'/><category scheme='http://www.blogger.com/atom/ns#' term='gcc'/><category scheme='http://www.blogger.com/atom/ns#' term='ld'/><category scheme='http://www.blogger.com/atom/ns#' term='as'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly'/><title type='text'>Step by step to MIPS assembly</title><content type='html'>In this article, I am going to introduce how to write MIPS assembly. All the examples introduced will able to be assembled or compiled into actual executable programs. They can be executed on a MIPS machine running Linux. So, let's forget the simulator and come to real world :-P. The first is the most simple program.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt;1 &lt;/span&gt;        &lt;span class="PreProc"&gt;.data&lt;/span&gt;
&lt;span class="lnr"&gt;2 &lt;/span&gt;        &lt;span class="PreProc"&gt;.text&lt;/span&gt;
&lt;span class="lnr"&gt;3 &lt;/span&gt;        &lt;span class="PreProc"&gt;.global&lt;/span&gt; &lt;span class="Function"&gt;__start&lt;/span&gt;
&lt;span class="lnr"&gt;4 &lt;/span&gt;&lt;span class="Function"&gt;__start&lt;/span&gt;:
&lt;span class="lnr"&gt;5 &lt;/span&gt;        &lt;span class="Keyword"&gt;li&lt;/span&gt; &lt;span class="Constant"&gt;$4&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;88&lt;/span&gt;
&lt;span class="lnr"&gt;6 &lt;/span&gt;        &lt;span class="Keyword"&gt;li&lt;/span&gt; &lt;span class="Constant"&gt;$2&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;4001&lt;/span&gt;
&lt;span class="lnr"&gt;7 &lt;/span&gt;        &lt;span class="Keyword"&gt;syscall&lt;/span&gt;&lt;/pre&gt;line 1: is an assembler directive which specifies that data section starts from here. It is empty since we don't have data section in this example.&lt;br /&gt;
line 2: specifies that text section starts from here.&lt;br /&gt;
line 3: specifies that __start is globally visible to all other modules that are part of the executable, and visible to the GNU linker. The symbol __start is required by the GNU Linker to specify the first instruction to be executed in a program, must always be a global one (same as _start for x86).&lt;br /&gt;
&lt;br /&gt;
line 4: specifies the entry of __start&lt;br /&gt;
line 5: loads immediate value 88 to $a3&lt;br /&gt;
line 6: loads immediate value 4001 to $a0&lt;br /&gt;
line 7: calls the OS to perform system call.&lt;br /&gt;
line 5~7: executes the system call according to the number stored in $a3. For MIPS O32 ABI, the number starts from 4000, and &lt;i&gt;exit()&lt;/i&gt; will be executed in this example. (You may reference linux kernel source include/asm-mips/unistd.h) The status code is stored in $a3, and we may check it by '&lt;i&gt;echo $?&lt;/i&gt;'.&lt;br /&gt;
&lt;br /&gt;
Assemble the source code with the cross assembler.&lt;br /&gt;
&lt;div style="color: purple;"&gt;&amp;nbsp; $ mipsel-linux-uclibc-as -o exit1.o exit1.s&lt;/div&gt;Link the object into an executable program.&lt;br /&gt;
&lt;div style="color: purple;"&gt;&amp;nbsp; $ mipsel-linux-uclibc-ld -o exit1 exit1.o&lt;/div&gt;Then, test the program.&lt;br /&gt;
&lt;div style="color: purple;"&gt;&amp;nbsp; $ exit1&lt;br /&gt;
&amp;nbsp; $ echo $?&lt;br /&gt;
&amp;nbsp; 88&lt;/div&gt;&lt;br /&gt;
OK. We have the skeleton of basic assembly source code. Normally, we don't write something like 'li $2, 4001', that is un-readable. It is easier to leverage definition of header files and the power of compiler. The same example calling &lt;i&gt;exit()&lt;/i&gt; could be re-written.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Include"&gt;#include &lt;/span&gt;&lt;span class="String"&gt;"asm/regdef.h"&lt;/span&gt;
&lt;span class="lnr"&gt; 2 &lt;/span&gt;&lt;span class="Include"&gt;#include &lt;/span&gt;&lt;span class="String"&gt;"asm/unistd.h"&lt;/span&gt;
&lt;span class="lnr"&gt; 3 &lt;/span&gt;
&lt;span class="lnr"&gt; 4 &lt;/span&gt;        &lt;span class="PreProc"&gt;.data&lt;/span&gt;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;        &lt;span class="PreProc"&gt;.text&lt;/span&gt;
&lt;span class="lnr"&gt; 6 &lt;/span&gt;        &lt;span class="PreProc"&gt;.global&lt;/span&gt; &lt;span class="Function"&gt;main&lt;/span&gt;
&lt;span class="lnr"&gt; 7 &lt;/span&gt;&lt;span class="Function"&gt;main&lt;/span&gt;:
&lt;span class="lnr"&gt; 8 &lt;/span&gt;        &lt;span class="PreProc"&gt;.set&lt;/span&gt; &lt;span class="Function"&gt;noreorder&lt;/span&gt;
&lt;span class="lnr"&gt; 9 &lt;/span&gt;        &lt;span class="PreProc"&gt;.cpload&lt;/span&gt;        &lt;span class="Identifier"&gt;t9&lt;/span&gt;             &lt;span class="Comment"&gt;# PIC ABI crap (function prologue)&lt;/span&gt;
&lt;span class="lnr"&gt;10 &lt;/span&gt;        &lt;span class="PreProc"&gt;.set&lt;/span&gt; &lt;span class="Function"&gt;reorder&lt;/span&gt;
&lt;span class="lnr"&gt;11 &lt;/span&gt;        &lt;span class="Keyword"&gt;li&lt;/span&gt; &lt;span class="Identifier"&gt;a0&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;99&lt;/span&gt;
&lt;span class="lnr"&gt;12 &lt;/span&gt;        &lt;span class="Keyword"&gt;li&lt;/span&gt; &lt;span class="Identifier"&gt;v0&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Function"&gt;__NR_exit&lt;/span&gt;
&lt;span class="lnr"&gt;13 &lt;/span&gt;        &lt;span class="Keyword"&gt;syscall&lt;/span&gt;&lt;/pre&gt;line 1: we need register definitions&lt;br /&gt;
line 2: we need system call index definitions&lt;br /&gt;
line 6~7: is just like &lt;i&gt;main()&lt;/i&gt; in a C program. Compiler will do some magic stuff (between &lt;i&gt;__start&lt;/i&gt; and &lt;i&gt;main&lt;/i&gt;) for our ease leveraging its power.&lt;br /&gt;
line 8~10: is the prologue of every function. Our program will compiled into a PIC, and linked  with C library. We need the compiler to calculate a correct offset for global pointer register. It is a must when we want to make a call to the dynamic C library. We are going to have the same prologue in the following examples.&lt;br /&gt;
&lt;br /&gt;
Compile the source code with cross compiler.&lt;br /&gt;
&lt;div style="color: purple;"&gt;&amp;nbsp; $ mipsel-linux-uclibc-gcc  -o exit2 exit2.S &lt;/div&gt;Test the program.&lt;br /&gt;
&lt;div style="color: purple;"&gt;&amp;nbsp; $ exit2&lt;br /&gt;
&amp;nbsp; $ echo $?&lt;br /&gt;
&amp;nbsp; 99 &lt;/div&gt;&lt;br /&gt;
Then, we may try to make some calls in our program. Instruction &lt;i&gt;jal&lt;/i&gt; let us call a procedure. It will automatically place the return address in $ra (GPR 31), so that we can easily return back by '&lt;i&gt;jr ra&lt;/i&gt;'. The following example calculates the value of (2^3 + 5^2).&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Comment"&gt;# The illustration the use of function.&lt;/span&gt;
&lt;span class="lnr"&gt; 2 &lt;/span&gt;&lt;span class="Comment"&gt;# This program will compute the value of 2^3 + 5^2.&lt;/span&gt;
&lt;span class="lnr"&gt; 3 &lt;/span&gt;
&lt;span class="lnr"&gt; 4 &lt;/span&gt;&lt;span class="Include"&gt;#include &lt;/span&gt;&lt;span class="String"&gt;"asm/regdef.h"&lt;/span&gt;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;&lt;span class="Include"&gt;#include &lt;/span&gt;&lt;span class="String"&gt;"asm/unistd.h"&lt;/span&gt;
&lt;span class="lnr"&gt; 6 &lt;/span&gt;
&lt;span class="lnr"&gt; 7 &lt;/span&gt;        &lt;span class="PreProc"&gt;.data&lt;/span&gt;
&lt;span class="lnr"&gt; 8 &lt;/span&gt;        &lt;span class="PreProc"&gt;.text&lt;/span&gt;
&lt;span class="lnr"&gt; 9 &lt;/span&gt;        &lt;span class="PreProc"&gt;.global&lt;/span&gt; &lt;span class="Function"&gt;main&lt;/span&gt;
&lt;span class="lnr"&gt;10 &lt;/span&gt;&lt;span class="Function"&gt;main&lt;/span&gt;:
&lt;span class="lnr"&gt;11 &lt;/span&gt;        &lt;span class="PreProc"&gt;.set&lt;/span&gt; &lt;span class="Function"&gt;noreorder&lt;/span&gt;
&lt;span class="lnr"&gt;12 &lt;/span&gt;        &lt;span class="PreProc"&gt;.cpload&lt;/span&gt;        &lt;span class="Identifier"&gt;t9&lt;/span&gt;             &lt;span class="Comment"&gt;# PIC ABI crap (function prologue)&lt;/span&gt;
&lt;span class="lnr"&gt;13 &lt;/span&gt;        &lt;span class="PreProc"&gt;.set&lt;/span&gt; &lt;span class="Function"&gt;reorder&lt;/span&gt;
&lt;span class="lnr"&gt;14 &lt;/span&gt;        &lt;span class="Keyword"&gt;subu&lt;/span&gt; &lt;span class="Identifier"&gt;sp&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;4&lt;/span&gt;             &lt;span class="Comment"&gt;# reserve 4bytes from stack&lt;/span&gt;
&lt;span class="lnr"&gt;15 &lt;/span&gt;        &lt;span class="Keyword"&gt;li&lt;/span&gt; &lt;span class="Identifier"&gt;a0&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;2&lt;/span&gt;
&lt;span class="lnr"&gt;16 &lt;/span&gt;        &lt;span class="Keyword"&gt;li&lt;/span&gt; &lt;span class="Identifier"&gt;a1&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;3&lt;/span&gt;
&lt;span class="lnr"&gt;17 &lt;/span&gt;        &lt;span class="Keyword"&gt;jal&lt;/span&gt; &lt;span class="Function"&gt;power&lt;/span&gt;              &lt;span class="Comment"&gt;# calculate 2^3&lt;/span&gt;
&lt;span class="lnr"&gt;18 &lt;/span&gt;        &lt;span class="Keyword"&gt;nop&lt;/span&gt;
&lt;span class="lnr"&gt;19 &lt;/span&gt;        &lt;span class="Keyword"&gt;sw&lt;/span&gt; &lt;span class="Identifier"&gt;v0&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;4&lt;/span&gt;(&lt;span class="Identifier"&gt;sp&lt;/span&gt;)           &lt;span class="Comment"&gt;# push the value of 2^3&lt;/span&gt;
&lt;span class="lnr"&gt;20 &lt;/span&gt;        &lt;span class="Keyword"&gt;nop&lt;/span&gt;
&lt;span class="lnr"&gt;21 &lt;/span&gt;        &lt;span class="Keyword"&gt;li&lt;/span&gt; &lt;span class="Identifier"&gt;a0&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;5&lt;/span&gt;
&lt;span class="lnr"&gt;22 &lt;/span&gt;        &lt;span class="Keyword"&gt;li&lt;/span&gt; &lt;span class="Identifier"&gt;a1&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;2&lt;/span&gt;
&lt;span class="lnr"&gt;23 &lt;/span&gt;        &lt;span class="Keyword"&gt;jal&lt;/span&gt; &lt;span class="Function"&gt;power&lt;/span&gt;              &lt;span class="Comment"&gt;# calculate 5^2&lt;/span&gt;
&lt;span class="lnr"&gt;24 &lt;/span&gt;        &lt;span class="Keyword"&gt;nop&lt;/span&gt;
&lt;span class="lnr"&gt;25 &lt;/span&gt;        &lt;span class="Keyword"&gt;lw&lt;/span&gt; &lt;span class="Identifier"&gt;a0&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;4&lt;/span&gt;(&lt;span class="Identifier"&gt;sp&lt;/span&gt;)           &lt;span class="Comment"&gt;# pop the value of 2^3&lt;/span&gt;
&lt;span class="lnr"&gt;26 &lt;/span&gt;        &lt;span class="Keyword"&gt;nop&lt;/span&gt;
&lt;span class="lnr"&gt;27 &lt;/span&gt;        &lt;span class="Keyword"&gt;addu&lt;/span&gt; &lt;span class="Identifier"&gt;sp&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;4&lt;/span&gt;             &lt;span class="Comment"&gt;# release 4bytes to stack&lt;/span&gt;
&lt;span class="lnr"&gt;28 &lt;/span&gt;        &lt;span class="Keyword"&gt;add&lt;/span&gt; &lt;span class="Identifier"&gt;a0&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Identifier"&gt;v0&lt;/span&gt;             &lt;span class="Comment"&gt;# add with 5^2&lt;/span&gt;
&lt;span class="lnr"&gt;29 &lt;/span&gt;        &lt;span class="Keyword"&gt;li&lt;/span&gt; &lt;span class="Identifier"&gt;v0&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Function"&gt;__NR_exit&lt;/span&gt;
&lt;span class="lnr"&gt;30 &lt;/span&gt;        &lt;span class="Keyword"&gt;syscall&lt;/span&gt;
&lt;span class="lnr"&gt;31 &lt;/span&gt;
&lt;span class="lnr"&gt;32 &lt;/span&gt;        &lt;span class="PreProc"&gt;.type&lt;/span&gt; &lt;span class="Function"&gt;power&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; @&lt;span class="Function"&gt;function&lt;/span&gt;
&lt;span class="lnr"&gt;33 &lt;/span&gt;&lt;span class="Function"&gt;power&lt;/span&gt;:
&lt;span class="lnr"&gt;34 &lt;/span&gt;        &lt;span class="Keyword"&gt;add&lt;/span&gt; &lt;span class="Identifier"&gt;v0&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Identifier"&gt;a0&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Identifier"&gt;zero&lt;/span&gt;       &lt;span class="Comment"&gt;# v0 = a0&lt;/span&gt;
&lt;span class="lnr"&gt;35 &lt;/span&gt;        &lt;span class="Keyword"&gt;subu&lt;/span&gt; &lt;span class="Identifier"&gt;a1&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;1&lt;/span&gt;
&lt;span class="lnr"&gt;36 &lt;/span&gt;        &lt;span class="Keyword"&gt;beqz&lt;/span&gt; &lt;span class="Identifier"&gt;a1&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Function"&gt;ans&lt;/span&gt;           &lt;span class="Comment"&gt;# power is 1&lt;/span&gt;
&lt;span class="lnr"&gt;37 &lt;/span&gt;        &lt;span class="Keyword"&gt;nop&lt;/span&gt;
&lt;span class="lnr"&gt;38 &lt;/span&gt;&lt;span class="Function"&gt;ploop&lt;/span&gt;:
&lt;span class="lnr"&gt;39 &lt;/span&gt;        &lt;span class="Keyword"&gt;mul&lt;/span&gt; &lt;span class="Identifier"&gt;v0&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Identifier"&gt;v0&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Identifier"&gt;a0&lt;/span&gt;         &lt;span class="Comment"&gt;# v0 * a0&lt;/span&gt;
&lt;span class="lnr"&gt;40 &lt;/span&gt;        &lt;span class="Keyword"&gt;subu&lt;/span&gt; &lt;span class="Identifier"&gt;a1&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;1&lt;/span&gt;             &lt;span class="Comment"&gt;# decrease the power&lt;/span&gt;
&lt;span class="lnr"&gt;41 &lt;/span&gt;        &lt;span class="Keyword"&gt;bnez&lt;/span&gt; &lt;span class="Identifier"&gt;a1&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Function"&gt;ploop&lt;/span&gt;         &lt;span class="Comment"&gt;# next power&lt;/span&gt;
&lt;span class="lnr"&gt;42 &lt;/span&gt;        &lt;span class="Keyword"&gt;nop&lt;/span&gt;
&lt;span class="lnr"&gt;43 &lt;/span&gt;&lt;span class="Function"&gt;ans&lt;/span&gt;:
&lt;span class="lnr"&gt;44 &lt;/span&gt;        &lt;span class="Keyword"&gt;jr&lt;/span&gt; &lt;span class="Identifier"&gt;ra&lt;/span&gt;
&lt;span class="lnr"&gt;45 &lt;/span&gt;        &lt;span class="Keyword"&gt;nop&lt;/span&gt;&lt;/pre&gt;line 14: reserves 4 bytes from stack that we are going to use.&lt;br /&gt;
line 15~16: passes argument to the function, &lt;i&gt;power()&lt;/i&gt;. The first argument ($a0) is base, and the second argument ($a1) is exponent.&lt;br /&gt;
line 17: calls &lt;i&gt;power()&lt;/i&gt;.&lt;br /&gt;
line 18: is branch delay slot for &lt;i&gt;jal&lt;/i&gt;&lt;br /&gt;
line 19~20: when &lt;i&gt;power()&lt;/i&gt; returns, the value of 2^3 will be stored in $v0. We save is to the stack.&lt;br /&gt;
line 21~24: calls &lt;i&gt;power()&lt;/i&gt; to calculate 5^2. It will be stored in $v0.&lt;br /&gt;
line 25~26: pop the stored value of 2^3 to $a0.&lt;br /&gt;
line 27: releases memory back to stack that we reserved.&lt;br /&gt;
line 28: adds $v0 (containing 5^2) with $a0 (containing 2^3).&lt;br /&gt;
line 29~30: calls &lt;i&gt;exit()&lt;/i&gt;. The final answer is in $v0.&lt;br /&gt;
line 32: marks the symbol &lt;i&gt;power&lt;/i&gt; as being a function name.&lt;br /&gt;
line 34: $v0 = $a0&lt;br /&gt;
line 35~37: if the exponent is equal to 1, the answer (in $v0) is equal to the base.&lt;br /&gt;
line 38~42: a loop to repeat calculation of multiplying base for (exponent - 1) times&lt;br /&gt;
line 43~45: returns to the original branch with final answer stored in $v0&lt;br /&gt;
&lt;br /&gt;
Compile the source code with cross compiler.&lt;br /&gt;
&lt;div style="color: purple;"&gt;&amp;nbsp; $ mipsel-linux-uclibc-gcc  -o power power.S &lt;/div&gt;Check the value of 2^3 + 5^2.&lt;br /&gt;
&lt;div style="color: purple;"&gt;&amp;nbsp; $ power&lt;br /&gt;
&amp;nbsp; $ echo $?&lt;br /&gt;
&amp;nbsp; 33 &lt;/div&gt;&lt;br /&gt;
Note that the previous example is a simple usage of function. Is is recommended to follow the O32 ABI calling convention for a better compatibility.&lt;br /&gt;
&lt;br /&gt;
With reference to previous example, you can write a hello-world program with &lt;i&gt;write&lt;/i&gt; system call. There is also &lt;a href="http://www.linux-mips.org/archives/linux-mips/2010-05/msg00234.html"&gt;an example&lt;/a&gt; provided in &lt;a href="http://www.linux-mips.org/archives/linux-mips/"&gt;Linux MIPS mailing list&lt;/a&gt;. How about a hello-world program calling C library printf? Take a look at the followed example.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Include"&gt;#include &lt;/span&gt;&lt;span class="String"&gt;"asm/regdef.h"&lt;/span&gt;
&lt;span class="lnr"&gt; 2 &lt;/span&gt;
&lt;span class="lnr"&gt; 3 &lt;/span&gt;        &lt;span class="PreProc"&gt;.globl&lt;/span&gt; &lt;span class="Function"&gt;main&lt;/span&gt;
&lt;span class="lnr"&gt; 4 &lt;/span&gt;&lt;span class="Function"&gt;main&lt;/span&gt;:   &lt;span class="PreProc"&gt;.ent&lt;/span&gt;    &lt;span class="Function"&gt;main&lt;/span&gt;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;        &lt;span class="PreProc"&gt;.frame&lt;/span&gt; &lt;span class="Identifier"&gt;sp&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;32&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Identifier"&gt;ra&lt;/span&gt;
&lt;span class="lnr"&gt; 6 &lt;/span&gt;        &lt;span class="PreProc"&gt;.set&lt;/span&gt;   &lt;span class="Function"&gt;noreorder&lt;/span&gt;
&lt;span class="lnr"&gt; 7 &lt;/span&gt;        &lt;span class="PreProc"&gt;.cpload&lt;/span&gt;        &lt;span class="Identifier"&gt;t9&lt;/span&gt;
&lt;span class="lnr"&gt; 8 &lt;/span&gt;        &lt;span class="PreProc"&gt;.set&lt;/span&gt;   &lt;span class="Function"&gt;reorder&lt;/span&gt;
&lt;span class="lnr"&gt; 9 &lt;/span&gt;
&lt;span class="lnr"&gt;10 &lt;/span&gt;        &lt;span class="Keyword"&gt;subu&lt;/span&gt;   &lt;span class="Identifier"&gt;sp&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Identifier"&gt;sp&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;32&lt;/span&gt;
&lt;span class="lnr"&gt;11 &lt;/span&gt;        &lt;span class="Keyword"&gt;sw&lt;/span&gt;     &lt;span class="Identifier"&gt;ra&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;28&lt;/span&gt;(&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt;12 &lt;/span&gt;        &lt;span class="PreProc"&gt;.cprestore&lt;/span&gt; &lt;span class="Constant"&gt;24&lt;/span&gt;
&lt;span class="lnr"&gt;13 &lt;/span&gt;        &lt;span class="Keyword"&gt;la&lt;/span&gt;     &lt;span class="Identifier"&gt;a0&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Function"&gt;hello&lt;/span&gt;
&lt;span class="lnr"&gt;14 &lt;/span&gt;        &lt;span class="Keyword"&gt;jal&lt;/span&gt;    &lt;span class="Function"&gt;printf&lt;/span&gt;
&lt;span class="lnr"&gt;15 &lt;/span&gt;
&lt;span class="lnr"&gt;16 &lt;/span&gt;        &lt;span class="Keyword"&gt;lw&lt;/span&gt;     &lt;span class="Identifier"&gt;ra&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;28&lt;/span&gt;(&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt;17 &lt;/span&gt;        &lt;span class="Keyword"&gt;addiu&lt;/span&gt;  &lt;span class="Identifier"&gt;sp&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Identifier"&gt;sp&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;32&lt;/span&gt;
&lt;span class="lnr"&gt;18 &lt;/span&gt;        &lt;span class="Keyword"&gt;jr&lt;/span&gt;     &lt;span class="Identifier"&gt;ra&lt;/span&gt;
&lt;span class="lnr"&gt;19 &lt;/span&gt;        &lt;span class="Macro"&gt;.end&lt;/span&gt;   &lt;span class="Function"&gt;main&lt;/span&gt;
&lt;span class="lnr"&gt;20 &lt;/span&gt;
&lt;span class="lnr"&gt;21 &lt;/span&gt;        &lt;span class="PreProc"&gt;.data&lt;/span&gt;
&lt;span class="lnr"&gt;22 &lt;/span&gt;&lt;span class="Function"&gt;hello&lt;/span&gt;:  &lt;span class="Type"&gt;.asciz&lt;/span&gt;  &lt;span class="String"&gt;"Hello world\n"&lt;/span&gt;&lt;/pre&gt;line 4: marks the entry of &lt;i&gt;main&lt;/i&gt;, the &lt;i&gt;.ent&lt;/i&gt; pseudo-op is used by the debugger.&lt;br /&gt;
line 5: tells compiler frame register is $sp, frame size is 32 bytes, and return register is $ra.&lt;br /&gt;
line 6~8: is the prologue described in previous example.&lt;br /&gt;
line 10: reserves the stack memory for 32 bytes. That includes space for local variables, saved registers, and argument area. Please reference the &lt;a href="http://winfred-lu.blogspot.com/2009/12/mips-calling-convention-with-gcc.html"&gt;calling convention article&lt;/a&gt; for detail.&lt;br /&gt;
&lt;br /&gt;
line 11: pushes the return address. When we call other functions, return address will be changed. Thus, it must be saved first.&lt;br /&gt;
line 12: restores the global pointer back. Because we will make a call that clobbers $gp, we have to restore the $gp value before returning. The idea is similar to line 11 that saving $ra.&lt;br /&gt;
&lt;br /&gt;
line 13: the argument is string "Hello world"&lt;br /&gt;
line 14: make a call to &lt;i&gt;printf&lt;/i&gt;&lt;br /&gt;
line 16: restores back the return address&lt;br /&gt;
line 17: release the stack that we reserved&lt;br /&gt;
line 18: returns from &lt;i&gt;main&lt;/i&gt; function&lt;br /&gt;
line 19: marks the end of &lt;i&gt;main&lt;/i&gt;&lt;br /&gt;
line 22: the "Hello world" string is stored in data section&lt;br /&gt;
&lt;br /&gt;
Compile the source code with cross compiler.&lt;br /&gt;
&lt;div style="color: purple;"&gt;&amp;nbsp; $ mipsel-linux-uclibc-gcc  -o printf printf.S &lt;/div&gt;Test the hello-world program.&lt;br /&gt;
&lt;div style="color: purple;"&gt;&amp;nbsp; $ printf&lt;br /&gt;
&amp;nbsp; Hello world&lt;/div&gt;&lt;br /&gt;
Having these examples for reference, I think it will be easier if you'd like to write assembly together with C programs.&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://sourceware.org/binutils/docs-2.20/"&gt;Documentation for binutils&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://sourceware.org/binutils/docs-2.20/as/index.html"&gt;Documentation for gas&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://faculty.cs.tamu.edu/klappi/arch/arch.html"&gt;Andreas Klappenecker, Computer Arcchitecture&lt;/a&gt; -- &lt;a href="http://faculty.cs.tamu.edu/klappi/arch/assembly1.ppt"&gt;Lecture3&lt;/a&gt;, &lt;a href="http://faculty.cs.tamu.edu/klappi/arch/assembly2.ppt"&gt;Lecture4&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://pages.cs.wisc.edu/%7Elarus/spim.html"&gt;SPIM, A MIPS32 Simulator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.cse.unsw.edu.au/%7Ecs3221/labs/assembler-intro.pdf"&gt;An Introduction to GNU assembler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://tigcc.ticalc.org/doc/gnuasm.html"&gt;TIGCC Team, GNU Assembler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.eecs.harvard.edu/%7Eellard/Courses/cs50-asm.pdf"&gt;Deniel J. Ellard, MIPS Assembly Language Programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.cs.wfu.edu/~torgerse/Kokua/More_SGI/007-2418-006/sgi_html/index.html"&gt;MIPSpro™ Assembly Language Programmer's Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.linux-mips.org/wiki/Main_Page"&gt;Linux MIPS wiki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://programminggroundup.blogspot.com/"&gt;Jonathan Bartlett, Programming from the Ground Up&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1626185782516232162-5155342910644164336?l=winfred-lu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://winfred-lu.blogspot.com/feeds/5155342910644164336/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1626185782516232162&amp;postID=5155342910644164336' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/5155342910644164336'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/5155342910644164336'/><link rel='alternate' type='text/html' href='http://winfred-lu.blogspot.com/2010/06/step-by-step-to-mips-assembly.html' title='Step by step to MIPS assembly'/><author><name>Winfred</name><uri>http://www.blogger.com/profile/15649970719010644298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm2.static.flickr.com/1104/569054989_83809a02b2_m.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1626185782516232162.post-3681954789589127950</id><published>2009-12-04T08:04:00.000-08:00</published><updated>2010-04-02T01:34:24.812-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mips'/><category scheme='http://www.blogger.com/atom/ns#' term='gnu'/><category scheme='http://www.blogger.com/atom/ns#' term='gcc'/><category scheme='http://www.blogger.com/atom/ns#' term='c'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly'/><title type='text'>MIPS calling convention with GCC</title><content type='html'>In this article, we are going to learn MIPS calling conventions by examples. And we will focus on the one used by GCC.  All the examples will be compiled with GCC flag &lt;i&gt;-mno-abicalls&lt;/i&gt;  not generating SVR4-style position-independent code. Normally &lt;i&gt;-mabicalls&lt;/i&gt;  should be used, we disable it for the simplification of assembly codes.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
First up, take a look at the most simple leaf function without any arguments.&lt;br /&gt;
&lt;pre&gt;&lt;span class="Type"&gt;int&lt;/span&gt; empty(&lt;span class="Type"&gt;void&lt;/span&gt;)
{
return 0;
}

&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Identifier"&gt;empty&lt;/span&gt;:
&lt;span class="lnr"&gt; 2 &lt;/span&gt;        &lt;span class="Identifier"&gt;addiu&lt;/span&gt;  $&lt;span class="Identifier"&gt;sp&lt;/span&gt;,$&lt;span class="Identifier"&gt;sp&lt;/span&gt;,-8
&lt;span class="lnr"&gt; 3 &lt;/span&gt;        &lt;span class="Identifier"&gt;sw&lt;/span&gt;     $&lt;span class="Identifier"&gt;fp&lt;/span&gt;,0($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt; 4 &lt;/span&gt;        &lt;span class="Identifier"&gt;move&lt;/span&gt;   $&lt;span class="Identifier"&gt;fp&lt;/span&gt;,$&lt;span class="Identifier"&gt;sp&lt;/span&gt;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;        &lt;span class="Identifier"&gt;move&lt;/span&gt;   $2,$0
&lt;span class="lnr"&gt; 6 &lt;/span&gt;        &lt;span class="Identifier"&gt;move&lt;/span&gt;   $&lt;span class="Identifier"&gt;sp&lt;/span&gt;,$&lt;span class="Identifier"&gt;fp&lt;/span&gt;
&lt;span class="lnr"&gt; 7 &lt;/span&gt;        &lt;span class="Identifier"&gt;lw&lt;/span&gt;     $&lt;span class="Identifier"&gt;fp&lt;/span&gt;,0($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt; 8 &lt;/span&gt;        &lt;span class="Identifier"&gt;addiu&lt;/span&gt;  $&lt;span class="Identifier"&gt;sp&lt;/span&gt;,$&lt;span class="Identifier"&gt;sp&lt;/span&gt;,8
&lt;span class="lnr"&gt; 9 &lt;/span&gt;        &lt;span class="Identifier"&gt;j&lt;/span&gt;      $31
&lt;span class="lnr"&gt;10 &lt;/span&gt;        &lt;span class="Identifier"&gt;nop&lt;/span&gt;&lt;/pre&gt;line 2: reserve 8 bytes stack space&lt;br /&gt;
line 3: push the previous $fp to stack&lt;br /&gt;
line 4: take current $sp as the subroutine's frame pointer&lt;br /&gt;
line 5: set $v0 to zero ($v0 stores the return value)&lt;br /&gt;
line 6,7,8: pop out $fp from stack, restore back original $sp&lt;br /&gt;
line 9: jump to return address&lt;br /&gt;
line 10: branch delay slot&lt;br /&gt;
&lt;br /&gt;
The function has its own stack frame. It must save the old frame pointer ($fp) before using it, and restore it back before returning to the caller. Generally speaking, if any of $16..$23 or $29..$31 is changed within the called function, it must be saved in the stack frame before use and restored from the stack frame before return from the function. It is called general register save area. As to the example, 4 bytes is enough for saving $fp, why does it reserve 8 bytes stack space? It is because that the register save area must be doubleword (8 byte) aligned.&lt;br /&gt;
&lt;br /&gt;
Besides saving $fp, a non-leaf function must save return address ($ra) as well. When it calls other subroutines, the $ra will be modified for returning from the subroutines. The non-leaf function has to save $ra in order to return to its caller.&lt;br /&gt;
&lt;pre&gt;&lt;span class="Type"&gt;int&lt;/span&gt; emptycaller(&lt;span class="Type"&gt;void&lt;/span&gt;)
{
empty();
&lt;span class="Statement"&gt;return&lt;/span&gt; 0;
}

&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Identifier"&gt;emptycaller&lt;/span&gt;:
&lt;span class="lnr"&gt; 2 &lt;/span&gt;        &lt;span class="Identifier"&gt;addiu&lt;/span&gt;  $&lt;span class="Identifier"&gt;sp&lt;/span&gt;,$&lt;span class="Identifier"&gt;sp&lt;/span&gt;,-24
&lt;span class="lnr"&gt; 3 &lt;/span&gt;        &lt;span class="Identifier"&gt;sw&lt;/span&gt;     $31,20($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt; 4 &lt;/span&gt;        &lt;span class="Identifier"&gt;sw&lt;/span&gt;     $&lt;span class="Identifier"&gt;fp&lt;/span&gt;,16($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt; 5 &lt;/span&gt;        &lt;span class="Identifier"&gt;move&lt;/span&gt;   $&lt;span class="Identifier"&gt;fp&lt;/span&gt;,$&lt;span class="Identifier"&gt;sp&lt;/span&gt;
&lt;span class="lnr"&gt; 6 &lt;/span&gt;        &lt;span class="Identifier"&gt;jal&lt;/span&gt;    &lt;span class="Identifier"&gt;empty&lt;/span&gt;
&lt;span class="lnr"&gt; 7 &lt;/span&gt;        &lt;span class="Identifier"&gt;nop&lt;/span&gt;
&lt;span class="lnr"&gt; 8 &lt;/span&gt;        &lt;span class="Identifier"&gt;move&lt;/span&gt;   $2,$0
&lt;span class="lnr"&gt; 9 &lt;/span&gt;        &lt;span class="Identifier"&gt;move&lt;/span&gt;   $&lt;span class="Identifier"&gt;sp&lt;/span&gt;,$&lt;span class="Identifier"&gt;fp&lt;/span&gt;
&lt;span class="lnr"&gt;10 &lt;/span&gt;        &lt;span class="Identifier"&gt;lw&lt;/span&gt;     $31,20($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt;11 &lt;/span&gt;        &lt;span class="Identifier"&gt;lw&lt;/span&gt;     $&lt;span class="Identifier"&gt;fp&lt;/span&gt;,16($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt;12 &lt;/span&gt;        &lt;span class="Identifier"&gt;addiu&lt;/span&gt;  $&lt;span class="Identifier"&gt;sp&lt;/span&gt;,$&lt;span class="Identifier"&gt;sp&lt;/span&gt;,24
&lt;span class="lnr"&gt;13 &lt;/span&gt;        &lt;span class="Identifier"&gt;j&lt;/span&gt;      $31
&lt;span class="lnr"&gt;14 &lt;/span&gt;        &lt;span class="Identifier"&gt;nop&lt;/span&gt;&lt;/pre&gt;line 3: push $ra onto the stack&lt;br /&gt;
line 4: push $fp onto the stack&lt;br /&gt;
line 10: pop $ra from the stack&lt;br /&gt;
line 11: pop $fp from the stack&lt;br /&gt;
In the example, 8 bytes stack space should be enough for saving $ra and $fp. The additional 16 bytes (total 24 bytes) is the function call arguemnt area, and we will dicuss about it later.&lt;br /&gt;
&lt;br /&gt;
We know that arguments are passed to subroutines in argument registers ($a0, $a1, $a2, and $a3). Let's take a look at the simple leaf function with 3 arguments.&lt;br /&gt;
&lt;pre&gt;&lt;span class="Type"&gt;int&lt;/span&gt; args3(&lt;span class="Type"&gt;int&lt;/span&gt; x, &lt;span class="Type"&gt;int&lt;/span&gt; y, &lt;span class="Type"&gt;int&lt;/span&gt; z)
{
&lt;span class="Statement"&gt;return&lt;/span&gt; (x + y + z);
}

&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Identifier"&gt;args3&lt;/span&gt;:
&lt;span class="lnr"&gt; 2 &lt;/span&gt;        &lt;span class="Identifier"&gt;addiu&lt;/span&gt;  $&lt;span class="Identifier"&gt;sp&lt;/span&gt;,$&lt;span class="Identifier"&gt;sp&lt;/span&gt;,-8
&lt;span class="lnr"&gt; 3 &lt;/span&gt;        &lt;span class="Identifier"&gt;sw&lt;/span&gt;     $&lt;span class="Identifier"&gt;fp&lt;/span&gt;,0($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt; 4 &lt;/span&gt;        &lt;span class="Identifier"&gt;move&lt;/span&gt;   $&lt;span class="Identifier"&gt;fp&lt;/span&gt;,$&lt;span class="Identifier"&gt;sp&lt;/span&gt;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;        &lt;span class="Identifier"&gt;sw&lt;/span&gt;     $4,8($&lt;span class="Identifier"&gt;fp&lt;/span&gt;)
&lt;span class="lnr"&gt; 6 &lt;/span&gt;        &lt;span class="Identifier"&gt;sw&lt;/span&gt;     $5,12($&lt;span class="Identifier"&gt;fp&lt;/span&gt;)
&lt;span class="lnr"&gt; 7 &lt;/span&gt;        &lt;span class="Identifier"&gt;sw&lt;/span&gt;     $6,16($&lt;span class="Identifier"&gt;fp&lt;/span&gt;)
&lt;span class="lnr"&gt; 8 &lt;/span&gt;        &lt;span class="Identifier"&gt;lw&lt;/span&gt;     $3,8($&lt;span class="Identifier"&gt;fp&lt;/span&gt;)
&lt;span class="lnr"&gt; 9 &lt;/span&gt;        &lt;span class="Identifier"&gt;lw&lt;/span&gt;     $2,12($&lt;span class="Identifier"&gt;fp&lt;/span&gt;)
&lt;span class="lnr"&gt;10 &lt;/span&gt;        &lt;span class="Identifier"&gt;nop&lt;/span&gt;
&lt;span class="lnr"&gt;11 &lt;/span&gt;        &lt;span class="Identifier"&gt;addu&lt;/span&gt;   $2,$3,$2
&lt;span class="lnr"&gt;12 &lt;/span&gt;        &lt;span class="Identifier"&gt;lw&lt;/span&gt;     $3,16($&lt;span class="Identifier"&gt;fp&lt;/span&gt;)
&lt;span class="lnr"&gt;13 &lt;/span&gt;        &lt;span class="Identifier"&gt;nop&lt;/span&gt;
&lt;span class="lnr"&gt;14 &lt;/span&gt;        &lt;span class="Identifier"&gt;addu&lt;/span&gt;   $2,$2,$3
&lt;span class="lnr"&gt;15 &lt;/span&gt;        &lt;span class="Identifier"&gt;move&lt;/span&gt;   $&lt;span class="Identifier"&gt;sp&lt;/span&gt;,$&lt;span class="Identifier"&gt;fp&lt;/span&gt;
&lt;span class="lnr"&gt;16 &lt;/span&gt;        &lt;span class="Identifier"&gt;lw&lt;/span&gt;     $&lt;span class="Identifier"&gt;fp&lt;/span&gt;,0($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt;17 &lt;/span&gt;        &lt;span class="Identifier"&gt;addiu&lt;/span&gt;  $&lt;span class="Identifier"&gt;sp&lt;/span&gt;,$&lt;span class="Identifier"&gt;sp&lt;/span&gt;,8
&lt;span class="lnr"&gt;18 &lt;/span&gt;        &lt;span class="Identifier"&gt;j&lt;/span&gt;      $31
&lt;span class="lnr"&gt;19 &lt;/span&gt;        &lt;span class="Identifier"&gt;nop&lt;/span&gt;&lt;/pre&gt;line 2~4: the function prologue as described previously&lt;br /&gt;
line 5~7: push the arguments from $a0, $a1, and $a2 to the stack&lt;br /&gt;
line 8~14: add the 3 arguments, and put the sum in $v0 for the return value&lt;br /&gt;
line 15~17: the function epilogue as described previously&lt;br /&gt;
line 18~19: return to the caller&lt;br /&gt;
The arguments are pushed to 8($fp) to 16($fp), which are located in the caller's stack frame. A non-leaf function (Caller) will always reserve the top 4 words (16 bytes) at least to storing arguments to called functions. It is called the function call argument area.&lt;br /&gt;
&lt;br /&gt;
If the maximum number of arguments to the called function is fewer than 4 words, the caller still has to reserve 4 words. Take the followed non-leaf function for example. The function reserved 24 bytes stack space instead of 8, and the additional 16 bytes is the function call argument area.&lt;br /&gt;
&lt;pre&gt;&lt;span class="Type"&gt;int&lt;/span&gt; arg3caller(&lt;span class="Type"&gt;void&lt;/span&gt;)
{
args3(5, 6, 7);
&lt;span class="Statement"&gt;return&lt;/span&gt; 0;
}

&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Identifier"&gt;arg3caller&lt;/span&gt;:
&lt;span class="lnr"&gt; 2 &lt;/span&gt;        &lt;span class="Identifier"&gt;addiu&lt;/span&gt;  $&lt;span class="Identifier"&gt;sp&lt;/span&gt;,$&lt;span class="Identifier"&gt;sp&lt;/span&gt;,-24
&lt;span class="lnr"&gt; 3 &lt;/span&gt;        &lt;span class="Identifier"&gt;sw&lt;/span&gt;     $31,20($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt; 4 &lt;/span&gt;        &lt;span class="Identifier"&gt;sw&lt;/span&gt;     $&lt;span class="Identifier"&gt;fp&lt;/span&gt;,16($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt; 5 &lt;/span&gt;        &lt;span class="Identifier"&gt;move&lt;/span&gt;   $&lt;span class="Identifier"&gt;fp&lt;/span&gt;,$&lt;span class="Identifier"&gt;sp&lt;/span&gt;
&lt;span class="lnr"&gt; 6 &lt;/span&gt;        &lt;span class="Identifier"&gt;li&lt;/span&gt;     $4,5                        # 0x5
&lt;span class="lnr"&gt; 7 &lt;/span&gt;        &lt;span class="Identifier"&gt;li&lt;/span&gt;     $5,6                        # 0x6
&lt;span class="lnr"&gt; 8 &lt;/span&gt;        &lt;span class="Identifier"&gt;li&lt;/span&gt;     $6,7                        # 0x7
&lt;span class="lnr"&gt; 9 &lt;/span&gt;        &lt;span class="Identifier"&gt;jal&lt;/span&gt;    &lt;span class="Identifier"&gt;args3&lt;/span&gt;
&lt;span class="lnr"&gt;10 &lt;/span&gt;        &lt;span class="Identifier"&gt;nop&lt;/span&gt;
&lt;span class="lnr"&gt;11 &lt;/span&gt;        &lt;span class="Identifier"&gt;move&lt;/span&gt;   $2,$0
&lt;span class="lnr"&gt;12 &lt;/span&gt;        &lt;span class="Identifier"&gt;move&lt;/span&gt;   $&lt;span class="Identifier"&gt;sp&lt;/span&gt;,$&lt;span class="Identifier"&gt;fp&lt;/span&gt;
&lt;span class="lnr"&gt;13 &lt;/span&gt;        &lt;span class="Identifier"&gt;lw&lt;/span&gt;     $31,20($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt;14 &lt;/span&gt;        &lt;span class="Identifier"&gt;lw&lt;/span&gt;     $&lt;span class="Identifier"&gt;fp&lt;/span&gt;,16($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt;15 &lt;/span&gt;        &lt;span class="Identifier"&gt;addiu&lt;/span&gt;  $&lt;span class="Identifier"&gt;sp&lt;/span&gt;,$&lt;span class="Identifier"&gt;sp&lt;/span&gt;,24
&lt;span class="lnr"&gt;16 &lt;/span&gt;        &lt;span class="Identifier"&gt;j&lt;/span&gt;      $31
&lt;span class="lnr"&gt;17 &lt;/span&gt;        &lt;span class="Identifier"&gt;nop&lt;/span&gt;&lt;/pre&gt;line 2: reserve 24 bytes stack space&lt;br /&gt;
line 3~4: Since 0($sp) ~ 12($sp) is function call argument area, the old $fp will be pushed onto 16($sp), and $ra will be pushed onto 20($sp).&lt;br /&gt;
line 6~10: pass the arguments in $a0, $a1, and $a2&lt;br /&gt;
&lt;br /&gt;
There are four argument registers ($a0, $a1, $a2, and $a3) totally. When calling a function with more than 4 arguemnts, the first 4 arguments are passed in registers, and the others are passed on the stack.&lt;br /&gt;
&lt;pre&gt;&lt;span class="Type"&gt;int&lt;/span&gt; args6(&lt;span class="Type"&gt;int&lt;/span&gt; x, &lt;span class="Type"&gt;int&lt;/span&gt; y, &lt;span class="Type"&gt;int&lt;/span&gt; z, &lt;span class="Type"&gt;int&lt;/span&gt; a, &lt;span class="Type"&gt;int&lt;/span&gt; b, &lt;span class="Type"&gt;int&lt;/span&gt; c)
{
&lt;span class="Statement"&gt;return&lt;/span&gt; (x + y + z + a + b + c);
}

&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Identifier"&gt;args6&lt;/span&gt;:
&lt;span class="lnr"&gt; 2 &lt;/span&gt;        &lt;span class="Identifier"&gt;addiu&lt;/span&gt;  $&lt;span class="Identifier"&gt;sp&lt;/span&gt;,$&lt;span class="Identifier"&gt;sp&lt;/span&gt;,-8
&lt;span class="lnr"&gt; 3 &lt;/span&gt;        &lt;span class="Identifier"&gt;sw&lt;/span&gt;     $&lt;span class="Identifier"&gt;fp&lt;/span&gt;,0($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt; 4 &lt;/span&gt;        &lt;span class="Identifier"&gt;move&lt;/span&gt;   $&lt;span class="Identifier"&gt;fp&lt;/span&gt;,$&lt;span class="Identifier"&gt;sp&lt;/span&gt;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;        &lt;span class="Identifier"&gt;sw&lt;/span&gt;     $4,8($&lt;span class="Identifier"&gt;fp&lt;/span&gt;)
&lt;span class="lnr"&gt; 6 &lt;/span&gt;        &lt;span class="Identifier"&gt;sw&lt;/span&gt;     $5,12($&lt;span class="Identifier"&gt;fp&lt;/span&gt;)
&lt;span class="lnr"&gt; 7 &lt;/span&gt;        &lt;span class="Identifier"&gt;sw&lt;/span&gt;     $6,16($&lt;span class="Identifier"&gt;fp&lt;/span&gt;)
&lt;span class="lnr"&gt; 8 &lt;/span&gt;        &lt;span class="Identifier"&gt;sw&lt;/span&gt;     $7,20($&lt;span class="Identifier"&gt;fp&lt;/span&gt;)
&lt;span class="lnr"&gt; 9 &lt;/span&gt;        &lt;span class="Identifier"&gt;lw&lt;/span&gt;     $3,8($&lt;span class="Identifier"&gt;fp&lt;/span&gt;)
&lt;span class="lnr"&gt;10 &lt;/span&gt;        &lt;span class="Identifier"&gt;lw&lt;/span&gt;     $2,12($&lt;span class="Identifier"&gt;fp&lt;/span&gt;)
&lt;span class="lnr"&gt;11 &lt;/span&gt;        &lt;span class="Identifier"&gt;nop&lt;/span&gt;
&lt;span class="lnr"&gt;12 &lt;/span&gt;        &lt;span class="Identifier"&gt;addu&lt;/span&gt;   $2,$3,$2
&lt;span class="lnr"&gt;13 &lt;/span&gt;        &lt;span class="Identifier"&gt;lw&lt;/span&gt;     $3,16($&lt;span class="Identifier"&gt;fp&lt;/span&gt;)
&lt;span class="lnr"&gt;14 &lt;/span&gt;        &lt;span class="Identifier"&gt;nop&lt;/span&gt;
&lt;span class="lnr"&gt;15 &lt;/span&gt;        &lt;span class="Identifier"&gt;addu&lt;/span&gt;   $2,$2,$3
&lt;span class="lnr"&gt;16 &lt;/span&gt;        &lt;span class="Identifier"&gt;lw&lt;/span&gt;     $3,20($&lt;span class="Identifier"&gt;fp&lt;/span&gt;)
&lt;span class="lnr"&gt;17 &lt;/span&gt;        &lt;span class="Identifier"&gt;nop&lt;/span&gt;
&lt;span class="lnr"&gt;18 &lt;/span&gt;        &lt;span class="Identifier"&gt;addu&lt;/span&gt;   $2,$2,$3
&lt;span class="lnr"&gt;19 &lt;/span&gt;        &lt;span class="Identifier"&gt;lw&lt;/span&gt;     $3,24($&lt;span class="Identifier"&gt;fp&lt;/span&gt;)
&lt;span class="lnr"&gt;20 &lt;/span&gt;        &lt;span class="Identifier"&gt;nop&lt;/span&gt;
&lt;span class="lnr"&gt;21 &lt;/span&gt;        &lt;span class="Identifier"&gt;addu&lt;/span&gt;   $2,$2,$3
&lt;span class="lnr"&gt;22 &lt;/span&gt;        &lt;span class="Identifier"&gt;lw&lt;/span&gt;     $3,28($&lt;span class="Identifier"&gt;fp&lt;/span&gt;)
&lt;span class="lnr"&gt;23 &lt;/span&gt;        &lt;span class="Identifier"&gt;nop&lt;/span&gt;
&lt;span class="lnr"&gt;24 &lt;/span&gt;        &lt;span class="Identifier"&gt;addu&lt;/span&gt;   $2,$2,$3
&lt;span class="lnr"&gt;25 &lt;/span&gt;        &lt;span class="Identifier"&gt;move&lt;/span&gt;   $&lt;span class="Identifier"&gt;sp&lt;/span&gt;,$&lt;span class="Identifier"&gt;fp&lt;/span&gt;
&lt;span class="lnr"&gt;26 &lt;/span&gt;        &lt;span class="Identifier"&gt;lw&lt;/span&gt;     $&lt;span class="Identifier"&gt;fp&lt;/span&gt;,0($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt;27 &lt;/span&gt;        &lt;span class="Identifier"&gt;addiu&lt;/span&gt;  $&lt;span class="Identifier"&gt;sp&lt;/span&gt;,$&lt;span class="Identifier"&gt;sp&lt;/span&gt;,8
&lt;span class="lnr"&gt;28 &lt;/span&gt;        &lt;span class="Identifier"&gt;j&lt;/span&gt;      $31
&lt;span class="lnr"&gt;29 &lt;/span&gt;        &lt;span class="Identifier"&gt;nop&lt;/span&gt;&lt;/pre&gt;line 2~4: function prologue&lt;br /&gt;
lin 5~8: push the first 4 arguments to the stack&lt;br /&gt;
line 9~18: add the first 4 arguments, and put the sum in $v0&lt;br /&gt;
line 19~21: fetch the 5th argument from 24($fp), and add it to $v0&lt;br /&gt;
line 22~24: fetch the 6th argument from 28($fp), and add it to $v0 for the return value&lt;br /&gt;
line 25~27: function epilogue&lt;br /&gt;
line 28~29: return to the caller&lt;br /&gt;
&lt;br /&gt;
In order to call the 6-argument function, the caller has to push the 5th and 6th arguments onto the stack. The function call argument area becomes of length 6 words (24 bytes) instead of 4 words. It reserves total 32 bytes, 8 bytes for registers $ra and $fp, and 24 bytes for function call argument area. Note that the area will also be doubleword aligned.&lt;br /&gt;
&lt;pre&gt;&lt;span class="Type"&gt;int&lt;/span&gt; arg6caller(&lt;span class="Type"&gt;void&lt;/span&gt;)
{
args5(5, 6, 7, 8, 9, 10);
&lt;span class="Statement"&gt;return&lt;/span&gt; 0;
}

&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Identifier"&gt;arg6caller&lt;/span&gt;:
&lt;span class="lnr"&gt; 2 &lt;/span&gt;        &lt;span class="Identifier"&gt;addiu&lt;/span&gt;  $&lt;span class="Identifier"&gt;sp&lt;/span&gt;,$&lt;span class="Identifier"&gt;sp&lt;/span&gt;,-32
&lt;span class="lnr"&gt; 3 &lt;/span&gt;        &lt;span class="Identifier"&gt;sw&lt;/span&gt;     $31,28($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt; 4 &lt;/span&gt;        &lt;span class="Identifier"&gt;sw&lt;/span&gt;     $&lt;span class="Identifier"&gt;fp&lt;/span&gt;,24($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt; 5 &lt;/span&gt;        &lt;span class="Identifier"&gt;move&lt;/span&gt;   $&lt;span class="Identifier"&gt;fp&lt;/span&gt;,$&lt;span class="Identifier"&gt;sp&lt;/span&gt;
&lt;span class="lnr"&gt; 6 &lt;/span&gt;        &lt;span class="Identifier"&gt;li&lt;/span&gt;     $2,9                        # 0x9
&lt;span class="lnr"&gt; 7 &lt;/span&gt;        &lt;span class="Identifier"&gt;sw&lt;/span&gt;     $2,16($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt; 8 &lt;/span&gt;        &lt;span class="Identifier"&gt;li&lt;/span&gt;     $2,10                       # 0xa
&lt;span class="lnr"&gt; 9 &lt;/span&gt;        &lt;span class="Identifier"&gt;sw&lt;/span&gt;     $2,20($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt;10 &lt;/span&gt;        &lt;span class="Identifier"&gt;li&lt;/span&gt;     $4,5                        # 0x5
&lt;span class="lnr"&gt;11 &lt;/span&gt;        &lt;span class="Identifier"&gt;li&lt;/span&gt;     $5,6                        # 0x6
&lt;span class="lnr"&gt;12 &lt;/span&gt;        &lt;span class="Identifier"&gt;li&lt;/span&gt;     $6,7                        # 0x7
&lt;span class="lnr"&gt;13 &lt;/span&gt;        &lt;span class="Identifier"&gt;li&lt;/span&gt;     $7,8                        # 0x8
&lt;span class="lnr"&gt;14 &lt;/span&gt;        &lt;span class="Identifier"&gt;jal&lt;/span&gt;    &lt;span class="Identifier"&gt;args5&lt;/span&gt;
&lt;span class="lnr"&gt;15 &lt;/span&gt;        &lt;span class="Identifier"&gt;nop&lt;/span&gt;
&lt;span class="lnr"&gt;16 &lt;/span&gt;        &lt;span class="Identifier"&gt;move&lt;/span&gt;   $2,$0
&lt;span class="lnr"&gt;17 &lt;/span&gt;        &lt;span class="Identifier"&gt;move&lt;/span&gt;   $&lt;span class="Identifier"&gt;sp&lt;/span&gt;,$&lt;span class="Identifier"&gt;fp&lt;/span&gt;
&lt;span class="lnr"&gt;18 &lt;/span&gt;        &lt;span class="Identifier"&gt;lw&lt;/span&gt;     $31,28($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt;19 &lt;/span&gt;        &lt;span class="Identifier"&gt;lw&lt;/span&gt;     $&lt;span class="Identifier"&gt;fp&lt;/span&gt;,24($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt;20 &lt;/span&gt;        &lt;span class="Identifier"&gt;addiu&lt;/span&gt;  $&lt;span class="Identifier"&gt;sp&lt;/span&gt;,$&lt;span class="Identifier"&gt;sp&lt;/span&gt;,32
&lt;span class="lnr"&gt;21 &lt;/span&gt;        &lt;span class="Identifier"&gt;j&lt;/span&gt;      $31
&lt;span class="lnr"&gt;22 &lt;/span&gt;        &lt;span class="Identifier"&gt;nop&lt;/span&gt;&lt;/pre&gt;line 2: reserve 32 bytes stack space&lt;br /&gt;
line 3~4: Since 0($sp) ~ 20($sp) is function call argument area, the old $fp will be pushed onto 16($sp), and $ra will be pushed onto 20($sp).&lt;br /&gt;
line 6~9: pass the 5th and 6th arguments on the stack&lt;br /&gt;
line 10~13: pass the first 4 arguments in argument registers&lt;br /&gt;
&lt;br /&gt;
Next, we are going to see a little bit complicated example. We declare 2 variables stored in registers $s0 and $s1. The function must save them in the general register save area before using them. Besides, we declare 2 local variables (automatic variables), and they will also be saved on the top of the general register save area.&lt;br /&gt;
&lt;pre&gt;&lt;span class="Type"&gt;int&lt;/span&gt; comp(&lt;span class="Type"&gt;int&lt;/span&gt; m, &lt;span class="Type"&gt;int&lt;/span&gt; n)
{
&lt;span class="Type"&gt;int&lt;/span&gt; a = 1, b = 2;
&lt;span class="Type"&gt;register&lt;/span&gt; &lt;span class="Type"&gt;int&lt;/span&gt; x = 5, y = 6;
args6(a, b, m, n, x, y);
&lt;span class="Statement"&gt;return&lt;/span&gt; (x + y);
}&lt;/pre&gt;Therefore, the stack frame will be like:&lt;br /&gt;
&lt;a href="http://4.bp.blogspot.com/_abhx4EO9uhw/SxkIdyPxw5I/AAAAAAAAAJ8/FDQa1XBQkC8/s1600-h/2009-12-04_203801.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5411365735059538834" src="http://4.bp.blogspot.com/_abhx4EO9uhw/SxkIdyPxw5I/AAAAAAAAAJ8/FDQa1XBQkC8/s320/2009-12-04_203801.png" style="cursor: pointer; height: 400px; width: 480px;" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
The assembly code line by line:&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Identifier"&gt;comp&lt;/span&gt;:
&lt;span class="lnr"&gt; 2 &lt;/span&gt;        &lt;span class="Identifier"&gt;addiu&lt;/span&gt;  $&lt;span class="Identifier"&gt;sp&lt;/span&gt;,$&lt;span class="Identifier"&gt;sp&lt;/span&gt;,-48
&lt;span class="lnr"&gt; 3 &lt;/span&gt;        &lt;span class="Identifier"&gt;sw&lt;/span&gt;     $31,44($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt; 4 &lt;/span&gt;        &lt;span class="Identifier"&gt;sw&lt;/span&gt;     $&lt;span class="Identifier"&gt;fp&lt;/span&gt;,40($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt; 5 &lt;/span&gt;        &lt;span class="Identifier"&gt;sw&lt;/span&gt;     $17,36($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt; 6 &lt;/span&gt;        &lt;span class="Identifier"&gt;sw&lt;/span&gt;     $16,32($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt; 7 &lt;/span&gt;        &lt;span class="Identifier"&gt;move&lt;/span&gt;   $&lt;span class="Identifier"&gt;fp&lt;/span&gt;,$&lt;span class="Identifier"&gt;sp&lt;/span&gt;
&lt;span class="lnr"&gt; 8 &lt;/span&gt;        &lt;span class="Identifier"&gt;sw&lt;/span&gt;     $4,48($&lt;span class="Identifier"&gt;fp&lt;/span&gt;)
&lt;span class="lnr"&gt; 9 &lt;/span&gt;        &lt;span class="Identifier"&gt;sw&lt;/span&gt;     $5,52($&lt;span class="Identifier"&gt;fp&lt;/span&gt;)
&lt;span class="lnr"&gt;10 &lt;/span&gt;        &lt;span class="Identifier"&gt;li&lt;/span&gt;     $2,1                        # 0x1
&lt;span class="lnr"&gt;11 &lt;/span&gt;        &lt;span class="Identifier"&gt;sw&lt;/span&gt;     $2,24($&lt;span class="Identifier"&gt;fp&lt;/span&gt;)
&lt;span class="lnr"&gt;12 &lt;/span&gt;        &lt;span class="Identifier"&gt;li&lt;/span&gt;     $2,2                        # 0x2
&lt;span class="lnr"&gt;13 &lt;/span&gt;        &lt;span class="Identifier"&gt;sw&lt;/span&gt;     $2,28($&lt;span class="Identifier"&gt;fp&lt;/span&gt;)
&lt;span class="lnr"&gt;14 &lt;/span&gt;        &lt;span class="Identifier"&gt;li&lt;/span&gt;     $16,5                       # 0x5
&lt;span class="lnr"&gt;15 &lt;/span&gt;        &lt;span class="Identifier"&gt;li&lt;/span&gt;     $17,6                       # 0x6
&lt;span class="lnr"&gt;16 &lt;/span&gt;        &lt;span class="Identifier"&gt;sw&lt;/span&gt;     $16,16($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt;17 &lt;/span&gt;        &lt;span class="Identifier"&gt;sw&lt;/span&gt;     $17,20($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt;18 &lt;/span&gt;        &lt;span class="Identifier"&gt;lw&lt;/span&gt;     $4,24($&lt;span class="Identifier"&gt;fp&lt;/span&gt;)
&lt;span class="lnr"&gt;19 &lt;/span&gt;        &lt;span class="Identifier"&gt;lw&lt;/span&gt;     $5,28($&lt;span class="Identifier"&gt;fp&lt;/span&gt;)
&lt;span class="lnr"&gt;20 &lt;/span&gt;        &lt;span class="Identifier"&gt;lw&lt;/span&gt;     $6,48($&lt;span class="Identifier"&gt;fp&lt;/span&gt;)
&lt;span class="lnr"&gt;21 &lt;/span&gt;        &lt;span class="Identifier"&gt;lw&lt;/span&gt;     $7,52($&lt;span class="Identifier"&gt;fp&lt;/span&gt;)
&lt;span class="lnr"&gt;22 &lt;/span&gt;        &lt;span class="Identifier"&gt;jal&lt;/span&gt;    &lt;span class="Identifier"&gt;args6&lt;/span&gt;
&lt;span class="lnr"&gt;23 &lt;/span&gt;        &lt;span class="Identifier"&gt;nop&lt;/span&gt;
&lt;span class="lnr"&gt;24 &lt;/span&gt;        &lt;span class="Identifier"&gt;addu&lt;/span&gt;   $2,$16,$17
&lt;span class="lnr"&gt;25 &lt;/span&gt;        &lt;span class="Identifier"&gt;move&lt;/span&gt;   $&lt;span class="Identifier"&gt;sp&lt;/span&gt;,$&lt;span class="Identifier"&gt;fp&lt;/span&gt;
&lt;span class="lnr"&gt;26 &lt;/span&gt;        &lt;span class="Identifier"&gt;lw&lt;/span&gt;     $31,44($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt;27 &lt;/span&gt;        &lt;span class="Identifier"&gt;lw&lt;/span&gt;     $&lt;span class="Identifier"&gt;fp&lt;/span&gt;,40($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt;28 &lt;/span&gt;        &lt;span class="Identifier"&gt;lw&lt;/span&gt;     $17,36($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt;29 &lt;/span&gt;        &lt;span class="Identifier"&gt;lw&lt;/span&gt;     $16,32($&lt;span class="Identifier"&gt;sp&lt;/span&gt;)
&lt;span class="lnr"&gt;30 &lt;/span&gt;        &lt;span class="Identifier"&gt;addiu&lt;/span&gt;  $&lt;span class="Identifier"&gt;sp&lt;/span&gt;,$&lt;span class="Identifier"&gt;sp&lt;/span&gt;,48
&lt;span class="lnr"&gt;31 &lt;/span&gt;        &lt;span class="Identifier"&gt;j&lt;/span&gt;      $31
&lt;span class="lnr"&gt;32 &lt;/span&gt;        &lt;span class="Identifier"&gt;nop&lt;/span&gt;&lt;/pre&gt;line 3~4: save previous $ra and $fp&lt;br /&gt;
line 5~6: save $s0 and $s1 before using it&lt;br /&gt;
line 8~9: save $a0 and $a1 (arguments m and n)&lt;br /&gt;
line 10~13: storing local variable a and b&lt;br /&gt;
line 14~15: variable x and y are saved in registers $s0 and $s1&lt;br /&gt;
line 16~17: pass arguments x and y on stack&lt;br /&gt;
line 18~21: pass arguments a, b, m, and n in argument registers&lt;br /&gt;
line 22~23: call the subroutine&lt;br /&gt;
line 24: put the sum of x + y to $v0 for the return value&lt;br /&gt;
line 26~30: restore registers back&lt;br /&gt;
line 31~32: return to the caller&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.linux-mips.org/wiki/MIPSABIHistory"&gt;Linux MIPS, MIPS ABI History&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://math-atlas.sourceforge.net/devel/assembly/mipsabi32.pdf"&gt;System V Application Binary Interface: MIPS(r) Processor Supplement, 3rd Edition&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.cs.ucsb.edu/%7Efranklin/30/spim/BookCallConvention.htm"&gt;Frank Lin, The rules for MIPS call convention&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.csl.cornell.edu/courses/ece314/MIPSXCallingXConventionsXSummary.pdf"&gt;Cornell University Course, MIPS Calling Conventions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1626185782516232162-3681954789589127950?l=winfred-lu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://winfred-lu.blogspot.com/feeds/3681954789589127950/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1626185782516232162&amp;postID=3681954789589127950' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/3681954789589127950'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/3681954789589127950'/><link rel='alternate' type='text/html' href='http://winfred-lu.blogspot.com/2009/12/mips-calling-convention-with-gcc.html' title='MIPS calling convention with GCC'/><author><name>Winfred</name><uri>http://www.blogger.com/profile/15649970719010644298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm2.static.flickr.com/1104/569054989_83809a02b2_m.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_abhx4EO9uhw/SxkIdyPxw5I/AAAAAAAAAJ8/FDQa1XBQkC8/s72-c/2009-12-04_203801.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1626185782516232162.post-272325111418860223</id><published>2009-11-19T01:25:00.000-08:00</published><updated>2010-03-31T19:59:17.617-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gcc'/><category scheme='http://www.blogger.com/atom/ns#' term='c99'/><category scheme='http://www.blogger.com/atom/ns#' term='c'/><title type='text'>C99 Features</title><content type='html'>Here is a simple example demonstrating some of the C99 features. It is a test program I wrote for learning from C99 standard. Although it doesn't cover all the new features for C99, I think it is at least a start for people who are not familiar to C99 like me.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt;  1 &lt;/span&gt;&lt;span class="PreProc"&gt;#include &lt;/span&gt;&lt;span class="Constant"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;
&lt;span class="lnr"&gt;  2 &lt;/span&gt;&lt;span class="PreProc"&gt;#include &lt;/span&gt;&lt;span class="Constant"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;
&lt;span class="lnr"&gt;  3 &lt;/span&gt;&lt;span class="PreProc"&gt;#include &lt;/span&gt;&lt;span class="Constant"&gt;&amp;lt;complex.h&amp;gt;&lt;/span&gt;
&lt;span class="lnr"&gt;  4 &lt;/span&gt;
&lt;span class="lnr"&gt;  5 &lt;/span&gt;&lt;span class="PreProc"&gt;#define ppp printf(&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="Special"&gt;%s&lt;/span&gt;&lt;span class="Constant"&gt;, line &lt;/span&gt;&lt;span class="Special"&gt;%d&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;&lt;span class="PreProc"&gt;, &lt;/span&gt;&lt;span class="Constant"&gt;__func__&lt;/span&gt;&lt;span class="PreProc"&gt;, &lt;/span&gt;&lt;span class="Constant"&gt;__LINE__&lt;/span&gt;&lt;span class="PreProc"&gt;)&lt;/span&gt;
&lt;span class="lnr"&gt;  6 &lt;/span&gt;
&lt;/pre&gt;line 3: include the header for complex definations and declarations&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt;  7 &lt;/span&gt;&lt;span class="Type"&gt;void&lt;/span&gt; data_type(&lt;span class="Type"&gt;void&lt;/span&gt;)
&lt;span class="lnr"&gt;  8 &lt;/span&gt;{
&lt;span class="lnr"&gt;  9 &lt;/span&gt;    _Bool b = &lt;span class="Number"&gt;2&lt;/span&gt;;
&lt;span class="lnr"&gt; 10 &lt;/span&gt;    &lt;span class="Type"&gt;long&lt;/span&gt; &lt;span class="Type"&gt;long&lt;/span&gt; &lt;span class="Type"&gt;int&lt;/span&gt; l;
&lt;span class="lnr"&gt; 11 &lt;/span&gt;    _Complex c = &lt;span class="Number"&gt;1&lt;/span&gt; + &lt;span class="Number"&gt;2.3&lt;/span&gt; * I;
&lt;span class="lnr"&gt; 12 &lt;/span&gt;    ppp;
&lt;span class="lnr"&gt; 13 &lt;/span&gt;
&lt;span class="lnr"&gt; 14 &lt;/span&gt;    printf(&lt;span class="Constant"&gt;"  b = &lt;/span&gt;&lt;span class="Special"&gt;%d&lt;/span&gt;&lt;span class="Constant"&gt;, sizeof b = &lt;/span&gt;&lt;span class="Special"&gt;%d&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;, b, &lt;span class="Statement"&gt;sizeof&lt;/span&gt;(b));
&lt;span class="lnr"&gt; 15 &lt;/span&gt;    printf(&lt;span class="Constant"&gt;"  sizeof l = &lt;/span&gt;&lt;span class="Special"&gt;%d&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;, &lt;span class="Statement"&gt;sizeof&lt;/span&gt;(l));
&lt;span class="lnr"&gt; 16 &lt;/span&gt;    printf(&lt;span class="Constant"&gt;"  c = &lt;/span&gt;&lt;span class="Special"&gt;%f&lt;/span&gt;&lt;span class="Constant"&gt; + &lt;/span&gt;&lt;span class="Special"&gt;%f&lt;/span&gt;&lt;span class="Constant"&gt; i, sizeof c = &lt;/span&gt;&lt;span class="Special"&gt;%d&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;, creal(c), cimag(c), &lt;span class="Statement"&gt;sizeof&lt;/span&gt;(c));
&lt;span class="lnr"&gt; 17 &lt;/span&gt;}
&lt;span class="lnr"&gt; 18 &lt;/span&gt;
&lt;/pre&gt;line 9: boolean type&lt;br /&gt;
line 10: long long type&lt;br /&gt;
line 11: comlex type&lt;br /&gt;
line 15: the value of a boolean variable can only be 0 or 1&lt;br /&gt;
line 16: print the real number and imaginary number of the complex number&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt; 19 &lt;/span&gt;&lt;span class="Type"&gt;void&lt;/span&gt; variable_length_array(&lt;span class="Type"&gt;int&lt;/span&gt; n)
&lt;span class="lnr"&gt; 20 &lt;/span&gt;{
&lt;span class="lnr"&gt; 21 &lt;/span&gt;    &lt;span class="Type"&gt;int&lt;/span&gt; arr[n];
&lt;span class="lnr"&gt; 22 &lt;/span&gt;    ppp;
&lt;span class="lnr"&gt; 23 &lt;/span&gt;
&lt;span class="lnr"&gt; 24 &lt;/span&gt;    printf(&lt;span class="Constant"&gt;"  arr: "&lt;/span&gt;);
&lt;span class="lnr"&gt; 25 &lt;/span&gt;    &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="Type"&gt;int&lt;/span&gt; i = &lt;span class="Number"&gt;0&lt;/span&gt;; i &amp;lt; n; i++) {
&lt;span class="lnr"&gt; 26 &lt;/span&gt;        arr[i] = i;
&lt;span class="lnr"&gt; 27 &lt;/span&gt;        printf(&lt;span class="Constant"&gt;"&lt;/span&gt;&lt;span class="Special"&gt;%d&lt;/span&gt;&lt;span class="Constant"&gt; "&lt;/span&gt;, arr[i]);
&lt;span class="lnr"&gt; 28 &lt;/span&gt;    }
&lt;span class="lnr"&gt; 29 &lt;/span&gt;    printf(&lt;span class="Constant"&gt;"&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;);
&lt;span class="lnr"&gt; 30 &lt;/span&gt;
&lt;span class="lnr"&gt; 31 &lt;/span&gt;    &lt;span class="Type"&gt;int&lt;/span&gt; arr2[n][n];
&lt;span class="lnr"&gt; 32 &lt;/span&gt;    printf(&lt;span class="Constant"&gt;"  size of arr2 = &lt;/span&gt;&lt;span class="Special"&gt;%d&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;, &lt;span class="Statement"&gt;sizeof&lt;/span&gt;(arr2)/&lt;span class="Statement"&gt;sizeof&lt;/span&gt;(&lt;span class="Type"&gt;int&lt;/span&gt;));
&lt;span class="lnr"&gt; 33 &lt;/span&gt;}
&lt;span class="lnr"&gt; 34 &lt;/span&gt;
&lt;/pre&gt;line 21: the lenght of the array is determined at run time&lt;br /&gt;
line 24: c++ style for loop initialization&lt;br /&gt;
line 31: two dimention array is fine, too&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt; 35 &lt;/span&gt;&lt;span class="PreProc"&gt;#define dprint(...) printf(__VA_ARGS__)&lt;/span&gt;
&lt;span class="lnr"&gt; 36 &lt;/span&gt;&lt;span class="Type"&gt;void&lt;/span&gt; variadic_macro(&lt;span class="Type"&gt;void&lt;/span&gt;)
&lt;span class="lnr"&gt; 37 &lt;/span&gt;{
&lt;span class="lnr"&gt; 38 &lt;/span&gt;    ppp;
&lt;span class="lnr"&gt; 39 &lt;/span&gt;    dprint(&lt;span class="Constant"&gt;"  hello!&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;);
&lt;span class="lnr"&gt; 40 &lt;/span&gt;    dprint(&lt;span class="Constant"&gt;"  &lt;/span&gt;&lt;span class="Special"&gt;%d&lt;/span&gt;&lt;span class="Constant"&gt; + &lt;/span&gt;&lt;span class="Special"&gt;%d&lt;/span&gt;&lt;span class="Constant"&gt; = &lt;/span&gt;&lt;span class="Special"&gt;%d&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;, &lt;span class="Number"&gt;2&lt;/span&gt;, &lt;span class="Number"&gt;1&lt;/span&gt;, &lt;span class="Number"&gt;3&lt;/span&gt;);
&lt;span class="lnr"&gt; 41 &lt;/span&gt;}
&lt;span class="lnr"&gt; 42 &lt;/span&gt;
&lt;/pre&gt;line 35: __VA_ARGS__ will be replaced by the passed arguments during macro expansion&lt;br /&gt;
line 39, 40: variable arguemnts are used for the macro&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt; 43 &lt;/span&gt;&lt;span class="Type"&gt;struct&lt;/span&gt; abc { &lt;span class="Type"&gt;int&lt;/span&gt; a; &lt;span class="Type"&gt;int&lt;/span&gt; b; &lt;span class="Type"&gt;int&lt;/span&gt; c[&lt;span class="Number"&gt;10&lt;/span&gt;]; };
&lt;span class="lnr"&gt; 44 &lt;/span&gt;&lt;span class="Type"&gt;int&lt;/span&gt; foo(&lt;span class="Type"&gt;void&lt;/span&gt;) { &lt;span class="Comment"&gt;/*&lt;/span&gt;&lt;span class="Comment"&gt; do something... &lt;/span&gt;&lt;span class="Comment"&gt;*/&lt;/span&gt; &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Number"&gt;0&lt;/span&gt;; }
&lt;span class="lnr"&gt; 45 &lt;/span&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt; 46 &lt;/span&gt;&lt;span class="Type"&gt;void&lt;/span&gt; designated_initializer(&lt;span class="Type"&gt;void&lt;/span&gt;)
&lt;span class="lnr"&gt; 47 &lt;/span&gt;{
&lt;span class="lnr"&gt; 48 &lt;/span&gt;    ppp;
&lt;span class="lnr"&gt; 49 &lt;/span&gt;
&lt;span class="lnr"&gt; 50 &lt;/span&gt;    &lt;span class="Type"&gt;struct&lt;/span&gt; abc s1 = { .b = &lt;span class="Number"&gt;1&lt;/span&gt;, .a = -&lt;span class="Number"&gt;1&lt;/span&gt; };
&lt;span class="lnr"&gt; 51 &lt;/span&gt;    &lt;span class="Type"&gt;struct&lt;/span&gt; abc s2 = { .c[&lt;span class="Number"&gt;2&lt;/span&gt;] = &lt;span class="Number"&gt;2&lt;/span&gt; };
&lt;span class="lnr"&gt; 52 &lt;/span&gt;    printf(&lt;span class="Constant"&gt;"  s1.a = &lt;/span&gt;&lt;span class="Special"&gt;%d&lt;/span&gt;&lt;span class="Constant"&gt;, s1.b = &lt;/span&gt;&lt;span class="Special"&gt;%d&lt;/span&gt;&lt;span class="Constant"&gt;, s2.c[2] = &lt;/span&gt;&lt;span class="Special"&gt;%d&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;, s1.a, s1.b, s2.c[&lt;span class="Number"&gt;2&lt;/span&gt;]);
&lt;span class="lnr"&gt; 53 &lt;/span&gt;
&lt;span class="lnr"&gt; 54 &lt;/span&gt;    &lt;span class="Type"&gt;int&lt;/span&gt; arr[&lt;span class="Number"&gt;10&lt;/span&gt;] = { [&lt;span class="Number"&gt;2&lt;/span&gt;] = &lt;span class="Number"&gt;22&lt;/span&gt;, [&lt;span class="Number"&gt;5&lt;/span&gt;] = &lt;span class="Number"&gt;55&lt;/span&gt; };
&lt;span class="lnr"&gt; 55 &lt;/span&gt;    &lt;span class="Type"&gt;struct&lt;/span&gt; abc s3[] = { [&lt;span class="Number"&gt;3&lt;/span&gt;].c[&lt;span class="Number"&gt;2&lt;/span&gt;] = &lt;span class="Number"&gt;33&lt;/span&gt; };
&lt;span class="lnr"&gt; 56 &lt;/span&gt;    printf(&lt;span class="Constant"&gt;"  arr[5] = &lt;/span&gt;&lt;span class="Special"&gt;%d&lt;/span&gt;&lt;span class="Constant"&gt;, s3[3].c[2] = &lt;/span&gt;&lt;span class="Special"&gt;%d&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;, arr[&lt;span class="Number"&gt;5&lt;/span&gt;], s3[&lt;span class="Number"&gt;3&lt;/span&gt;].c[&lt;span class="Number"&gt;2&lt;/span&gt;]);
&lt;span class="lnr"&gt; 57 &lt;/span&gt;
&lt;span class="lnr"&gt; 58 &lt;/span&gt;    &lt;span class="Type"&gt;struct&lt;/span&gt; abc s4 = { .b = &lt;span class="Number"&gt;4&lt;/span&gt;, .b = &lt;span class="Number"&gt;5&lt;/span&gt;, .b = &lt;span class="Number"&gt;6&lt;/span&gt; };
&lt;span class="lnr"&gt; 59 &lt;/span&gt;    printf(&lt;span class="Constant"&gt;"  s4.b = &lt;/span&gt;&lt;span class="Special"&gt;%d&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;, s4.b);
&lt;span class="lnr"&gt; 60 &lt;/span&gt;
&lt;span class="lnr"&gt; 61 &lt;/span&gt;    &lt;span class="Type"&gt;struct&lt;/span&gt; xx { &lt;span class="Type"&gt;int&lt;/span&gt; x; &lt;span class="Type"&gt;struct&lt;/span&gt; abc sub; };
&lt;span class="lnr"&gt; 62 &lt;/span&gt;    &lt;span class="Type"&gt;struct&lt;/span&gt; xx s5 = { .sub.b = &lt;span class="Number"&gt;5&lt;/span&gt; };
&lt;span class="lnr"&gt; 63 &lt;/span&gt;    &lt;span class="Type"&gt;struct&lt;/span&gt; xx s6 = { .sub = s1 };
&lt;span class="lnr"&gt; 64 &lt;/span&gt;    printf(&lt;span class="Constant"&gt;"  s5.sub.b = &lt;/span&gt;&lt;span class="Special"&gt;%d&lt;/span&gt;&lt;span class="Constant"&gt;, s6.sub.b = &lt;/span&gt;&lt;span class="Special"&gt;%d&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;, s5.sub.b, s6.sub.b);
&lt;span class="lnr"&gt; 65 &lt;/span&gt;}
&lt;span class="lnr"&gt; 66 &lt;/span&gt;
&lt;/pre&gt;line 50: members can be named in initializer lists&lt;br /&gt;
line 51: initialize only the 3rd object for the array member c&lt;br /&gt;
line 54, 55: initialize some array objects only&lt;br /&gt;
line 58: initialize several times, and the last one wins&lt;br /&gt;
line 62: initialize member b of the sub structure&lt;br /&gt;
line 63: initialize only the sub structure&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt; 67 &lt;/span&gt;&lt;span class="Type"&gt;void&lt;/span&gt; cl(&lt;span class="Type"&gt;struct&lt;/span&gt; abc s)
&lt;span class="lnr"&gt; 68 &lt;/span&gt;{
&lt;span class="lnr"&gt; 69 &lt;/span&gt;    printf(&lt;span class="Constant"&gt;"  s.a = &lt;/span&gt;&lt;span class="Special"&gt;%d&lt;/span&gt;&lt;span class="Constant"&gt;, s.b = &lt;/span&gt;&lt;span class="Special"&gt;%d&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;, s.a, s.b);
&lt;span class="lnr"&gt; 70 &lt;/span&gt;}
&lt;span class="lnr"&gt; 71 &lt;/span&gt;&lt;span class="Type"&gt;void&lt;/span&gt; compound_literal(&lt;span class="Type"&gt;void&lt;/span&gt;)
&lt;span class="lnr"&gt; 72 &lt;/span&gt;{
&lt;span class="lnr"&gt; 73 &lt;/span&gt;    &lt;span class="Type"&gt;int&lt;/span&gt; *p = (&lt;span class="Type"&gt;int&lt;/span&gt; []){&lt;span class="Number"&gt;1&lt;/span&gt;, &lt;span class="Number"&gt;2&lt;/span&gt;, &lt;span class="Number"&gt;3&lt;/span&gt;};
&lt;span class="lnr"&gt; 74 &lt;/span&gt;    ppp;
&lt;span class="lnr"&gt; 75 &lt;/span&gt;
&lt;span class="lnr"&gt; 76 &lt;/span&gt;    printf(&lt;span class="Constant"&gt;"  *p = &lt;/span&gt;&lt;span class="Special"&gt;%d&lt;/span&gt;&lt;span class="Constant"&gt;, *(p+1) = &lt;/span&gt;&lt;span class="Special"&gt;%d&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;, *p, *(p+&lt;span class="Number"&gt;1&lt;/span&gt;));
&lt;span class="lnr"&gt; 77 &lt;/span&gt;    cl((&lt;span class="Type"&gt;struct&lt;/span&gt; abc){ .a=&lt;span class="Number"&gt;9&lt;/span&gt;, .b=&lt;span class="Number"&gt;8&lt;/span&gt; });
&lt;span class="lnr"&gt; 78 &lt;/span&gt;}
&lt;span class="lnr"&gt; 79 &lt;/span&gt;
&lt;/pre&gt;line 73: composed with a construct with a brace'd initializer to create unnamed array's.&lt;br /&gt;
line 77: pass a compound literal argument to function cl (both compound literal and designated initializer are used)&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt; 80 &lt;/span&gt;&lt;span class="Type"&gt;void&lt;/span&gt; flexible_array_member(&lt;span class="Type"&gt;void&lt;/span&gt;)
&lt;span class="lnr"&gt; 81 &lt;/span&gt;{
&lt;span class="lnr"&gt; 82 &lt;/span&gt;    &lt;span class="Type"&gt;struct&lt;/span&gt; xx { &lt;span class="Type"&gt;int&lt;/span&gt; a; &lt;span class="Type"&gt;int&lt;/span&gt; arr[]; };
&lt;span class="lnr"&gt; 83 &lt;/span&gt;    &lt;span class="Type"&gt;struct&lt;/span&gt; xx *p;
&lt;span class="lnr"&gt; 84 &lt;/span&gt;
&lt;span class="lnr"&gt; 85 &lt;/span&gt;    p = malloc(&lt;span class="Number"&gt;10&lt;/span&gt; * &lt;span class="Statement"&gt;sizeof&lt;/span&gt;(&lt;span class="Type"&gt;int&lt;/span&gt;));
&lt;span class="lnr"&gt; 86 &lt;/span&gt;    p-&amp;gt;arr[&lt;span class="Number"&gt;9&lt;/span&gt;] = &lt;span class="Number"&gt;9&lt;/span&gt;;
&lt;span class="lnr"&gt; 87 &lt;/span&gt;    printf(&lt;span class="Constant"&gt;"  p-&amp;gt;arr[9] = &lt;/span&gt;&lt;span class="Special"&gt;%d&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;, p-&amp;gt;arr[&lt;span class="Number"&gt;9&lt;/span&gt;]);
&lt;span class="lnr"&gt; 88 &lt;/span&gt;    free(p);
&lt;span class="lnr"&gt; 89 &lt;/span&gt;
&lt;span class="lnr"&gt; 90 &lt;/span&gt;    p = malloc(&lt;span class="Number"&gt;20&lt;/span&gt; * &lt;span class="Statement"&gt;sizeof&lt;/span&gt;(&lt;span class="Type"&gt;int&lt;/span&gt;));
&lt;span class="lnr"&gt; 91 &lt;/span&gt;    p-&amp;gt;arr[&lt;span class="Number"&gt;19&lt;/span&gt;] = &lt;span class="Number"&gt;19&lt;/span&gt;;
&lt;span class="lnr"&gt; 92 &lt;/span&gt;    printf(&lt;span class="Constant"&gt;"  p-&amp;gt;arr[19] = &lt;/span&gt;&lt;span class="Special"&gt;%d&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;, p-&amp;gt;arr[&lt;span class="Number"&gt;19&lt;/span&gt;]);
&lt;span class="lnr"&gt; 93 &lt;/span&gt;    free(p);
&lt;span class="lnr"&gt; 94 &lt;/span&gt;}
&lt;span class="lnr"&gt; 95 &lt;/span&gt;
&lt;/pre&gt;line 82: incomplete array without bounds of struct members is allowed (it must be the last member)&lt;br /&gt;
line 85: set p to a struct xx with array of length 9&lt;br /&gt;
line 90: set p to another struct xx with array of length 19&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt; 96 &lt;/span&gt;&lt;span class="Type"&gt;int&lt;/span&gt; main(&lt;span class="Type"&gt;void&lt;/span&gt;)
&lt;span class="lnr"&gt; 97 &lt;/span&gt;{
&lt;span class="lnr"&gt; 98 &lt;/span&gt;    data_type();
&lt;span class="lnr"&gt; 99 &lt;/span&gt;    variable_length_array(&lt;span class="Number"&gt;5&lt;/span&gt;);
&lt;span class="lnr"&gt;100 &lt;/span&gt;    variadic_macro();
&lt;span class="lnr"&gt;101 &lt;/span&gt;    designated_initializer();
&lt;span class="lnr"&gt;102 &lt;/span&gt;    compound_literal();
&lt;span class="lnr"&gt;103 &lt;/span&gt;    flexible_array_member();
&lt;span class="lnr"&gt;104 &lt;/span&gt;
&lt;span class="lnr"&gt;105 &lt;/span&gt;    &lt;span class="Comment"&gt;//return 0;&lt;/span&gt;
&lt;span class="lnr"&gt;106 &lt;/span&gt;}
&lt;/pre&gt;line 105: compiler will add a '&lt;span style="font-style: italic;"&gt;return 0;&lt;/span&gt;' implicitly&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The result of this program:&lt;br /&gt;
&lt;pre&gt;$ gcc -Wall -std=c99 c99.c
$ ./a.out

data_type, line 12
b = 1, sizeof b = 1
sizeof l = 8
c = 1.000000 + 2.300000 i, sizeof c = 16

variable_length_array, line 22
arr: 0 1 2 3 4
size of arr2 = 25

variadic_macro, line 38
hello!
2 + 1 = 3

designated_initializer, line 48
s1.a = -1, s1.b = 1, s2.c[2] = 2
arr[5] = 55, s3[3].c[2] = 33
s4.b = 6
s5.sub.b = 5, s6.sub.b = 1

compound_literal, line 74
*p = 1, *(p+1) = 2
s.a = 9, s.b = 8
p-&amp;gt;arr[9] = 9
p-&amp;gt;arr[19] = 19
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1336.pdf"&gt;Draft of the C99 standard with corrigenda TC1, TC2, and TC3 included&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.open-std.org/jtc1/sc22/wg14/www/newinc9x.htm"&gt;Open Standard, "New in C9X"&lt;/a&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/C99"&gt;wikipedia, "C99"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://gcc.gnu.org/c99status.html"&gt;GCC document, "Status of C99 features in GCC"&lt;/a&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family: arial,Helvetica,Sans-Serif; font-size: 85%;"&gt;&lt;a class="light" href="http://www.kuro5hin.org/user/Carnage4Life"&gt;&lt;/a&gt;&lt;/span&gt;&lt;a href="http://www.kuro5hin.org/story/2001/2/23/194544/139"&gt;Carnage4Life at Kuro5hin, "Are You Ready for C99?"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.comeaucomputing.com/techtalk/c99/"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;Comeau Computing, "Tech Talk about C99"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://home.datacomm.ch/t_wolf/tw/c/c9x_changes.html"&gt;        Thomas Wolf, "The New ISO Standard for C (C9X)"&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1626185782516232162-272325111418860223?l=winfred-lu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://winfred-lu.blogspot.com/feeds/272325111418860223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1626185782516232162&amp;postID=272325111418860223' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/272325111418860223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/272325111418860223'/><link rel='alternate' type='text/html' href='http://winfred-lu.blogspot.com/2009/11/c99-features.html' title='C99 Features'/><author><name>Winfred</name><uri>http://www.blogger.com/profile/15649970719010644298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm2.static.flickr.com/1104/569054989_83809a02b2_m.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1626185782516232162.post-4112076658011844554</id><published>2009-11-16T03:36:00.000-08:00</published><updated>2010-03-31T20:00:56.649-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gcc'/><category scheme='http://www.blogger.com/atom/ns#' term='x86'/><category scheme='http://www.blogger.com/atom/ns#' term='c'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly'/><title type='text'>Learning x86 Calling Conventions by Examples</title><content type='html'>The x86 architecture features many different calling conventions. There are three major calling conventions in use: &lt;span style="color: #330099; font-style: italic;"&gt;__cdecl&lt;/span&gt;, &lt;span style="color: #330099; font-style: italic;"&gt;__stdcall&lt;/span&gt;, and &lt;span style="color: #330099; font-style: italic;"&gt;__fastcall&lt;/span&gt;. We are going to force the compiler to generate assembly with different calling conventions in order to see how they work.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Here is a simple function in C:&lt;br /&gt;
&lt;pre&gt;&lt;span class="Type"&gt;int&lt;/span&gt; f(&lt;span class="Type"&gt;int&lt;/span&gt; a, &lt;span class="Type"&gt;int&lt;/span&gt; b)
{
&lt;span class="Statement"&gt;return&lt;/span&gt; a + b;
}
&lt;/pre&gt;&lt;br /&gt;
GCC compiler uses &lt;span style="color: #330099; font-style: italic;"&gt;__cdecl&lt;/span&gt; by default (It is also the default calling convention for Microsoft C/C++ compiler). We will get the same result as &lt;span style="color: #330099; font-style: italic;"&gt;__cdecl&lt;/span&gt; without extra compiler options or configurations.&lt;br /&gt;
&lt;br /&gt;
Let's call the simple function with &lt;span style="color: #330099; font-style: italic;"&gt;__cdecl&lt;/span&gt; calling convention:&lt;br /&gt;
&lt;pre&gt;&lt;span class="Type"&gt;int&lt;/span&gt; __attribute__((cdecl)) f(&lt;span class="Type"&gt;int&lt;/span&gt; a, &lt;span class="Type"&gt;int&lt;/span&gt; b)
{
&lt;span class="Statement"&gt;return&lt;/span&gt; a + b;
}
&lt;span class="Type"&gt;void&lt;/span&gt; caller(&lt;span class="Type"&gt;void&lt;/span&gt;)
{
f(&lt;span class="Number"&gt;3&lt;/span&gt;, &lt;span class="Number"&gt;5&lt;/span&gt;);
}
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
The assembly generated by gcc for &lt;span style="color: #330099; font-style: italic;"&gt;__cdecl&lt;/span&gt; would be:&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Identifier"&gt;f&lt;/span&gt;:
&lt;span class="lnr"&gt; 2 &lt;/span&gt;        &lt;span class="Identifier"&gt;pushl&lt;/span&gt;  %&lt;span class="Identifier"&gt;ebp&lt;/span&gt;
&lt;span class="lnr"&gt; 3 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   %&lt;span class="Identifier"&gt;esp&lt;/span&gt;, %&lt;span class="Identifier"&gt;ebp&lt;/span&gt;
&lt;span class="lnr"&gt; 4 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   &lt;span class="Number"&gt;12&lt;/span&gt;(%&lt;span class="Identifier"&gt;ebp&lt;/span&gt;), %&lt;span class="Identifier"&gt;eax&lt;/span&gt;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;        &lt;span class="Identifier"&gt;addl&lt;/span&gt;   &lt;span class="Number"&gt;8&lt;/span&gt;(%&lt;span class="Identifier"&gt;ebp&lt;/span&gt;), %&lt;span class="Identifier"&gt;eax&lt;/span&gt;
&lt;span class="lnr"&gt; 6 &lt;/span&gt;        &lt;span class="Identifier"&gt;popl&lt;/span&gt;   %&lt;span class="Identifier"&gt;ebp&lt;/span&gt;
&lt;span class="lnr"&gt; 7 &lt;/span&gt;        &lt;span class="Identifier"&gt;ret&lt;/span&gt;
&lt;span class="lnr"&gt; 8 &lt;/span&gt;&lt;span class="Identifier"&gt;caller&lt;/span&gt;:
&lt;span class="lnr"&gt; 9 &lt;/span&gt;        &lt;span class="Identifier"&gt;pushl&lt;/span&gt;  %&lt;span class="Identifier"&gt;ebp&lt;/span&gt;
&lt;span class="lnr"&gt;10 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   %&lt;span class="Identifier"&gt;esp&lt;/span&gt;, %&lt;span class="Identifier"&gt;ebp&lt;/span&gt;
&lt;span class="lnr"&gt;11 &lt;/span&gt;        &lt;span class="Identifier"&gt;subl&lt;/span&gt;   $&lt;span class="Number"&gt;8&lt;/span&gt;, %&lt;span class="Identifier"&gt;esp&lt;/span&gt;
&lt;span class="lnr"&gt;12 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   $&lt;span class="Number"&gt;5&lt;/span&gt;, &lt;span class="Number"&gt;4&lt;/span&gt;(%&lt;span class="Identifier"&gt;esp&lt;/span&gt;)
&lt;span class="lnr"&gt;13 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   $&lt;span class="Number"&gt;3&lt;/span&gt;, (%&lt;span class="Identifier"&gt;esp&lt;/span&gt;)
&lt;span class="lnr"&gt;14 &lt;/span&gt;        &lt;span class="Identifier"&gt;call&lt;/span&gt;   &lt;span class="Identifier"&gt;f&lt;/span&gt;
&lt;span class="lnr"&gt;15 &lt;/span&gt;        &lt;span class="Identifier"&gt;leave&lt;/span&gt;
&lt;span class="lnr"&gt;16 &lt;/span&gt;        &lt;span class="Identifier"&gt;ret&lt;/span&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Calling a &lt;span style="color: #330099; font-style: italic;"&gt;__cdecl&lt;/span&gt; function line by line:&lt;br /&gt;
&lt;br /&gt;
Push parameters onto the stack, from right to left. In this example, 5 first and then 3.&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt;12 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   $&lt;span class="Number"&gt;5&lt;/span&gt;, &lt;span class="Number"&gt;4&lt;/span&gt;(%&lt;span class="Identifier"&gt;esp&lt;/span&gt;)
&lt;span class="lnr"&gt;13 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   $&lt;span class="Number"&gt;3&lt;/span&gt;, (%&lt;span class="Identifier"&gt;esp&lt;/span&gt;)
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Call the function f. The process will push the content of %eip onto the stack (for the return address of function f).&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt;14 &lt;/span&gt;        &lt;span class="Identifier"&gt;call&lt;/span&gt;   &lt;span class="Identifier"&gt;f&lt;/span&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Since we are in the new function f, a new local stack frame is needed. We push the current %ebp (which belongs to the caller's frame) onto the stack, and make it point to the top of the stack (%esp).&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt; 2 &lt;/span&gt;        &lt;span class="Identifier"&gt;pushl&lt;/span&gt;  %&lt;span class="Identifier"&gt;ebp&lt;/span&gt;
&lt;span class="lnr"&gt; 3 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   %&lt;span class="Identifier"&gt;esp&lt;/span&gt;, %&lt;span class="Identifier"&gt;ebp&lt;/span&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
After %ebp is changed, the arguments of the function f will be referred as 8(%ebp) and 12(%ebp). They are summed to %eax, which will be the return value to the caller. Note that 0(%ebp) is the old (caller's) base pointer, and 4(%ebp) is the old instruction pointer.&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt; 4 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   &lt;span class="Number"&gt;12&lt;/span&gt;(%&lt;span class="Identifier"&gt;ebp&lt;/span&gt;), %&lt;span class="Identifier"&gt;eax&lt;/span&gt;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;        &lt;span class="Identifier"&gt;addl&lt;/span&gt;   &lt;span class="Number"&gt;8&lt;/span&gt;(%&lt;span class="Identifier"&gt;ebp&lt;/span&gt;), %&lt;span class="Identifier"&gt;eax&lt;/span&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Restore the saved base pointer %ebp.&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt; 6 &lt;/span&gt;        &lt;span class="Identifier"&gt;popl&lt;/span&gt;   %&lt;span class="Identifier"&gt;ebp&lt;/span&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Return from the function. It will pop the old %eip and jump to the location.&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt; 7 &lt;/span&gt;        &lt;span class="Identifier"&gt;ret&lt;/span&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Note that line 9, 10 and line 2, 3 pairs are the same. It is the function prologue used for every function. Line 8 reserves space for arguments of function f. Line 9 to 11 together is actually the same as ENTER instruction. The compiler uses 3 instructions instead of ENTER instruction for performance. &lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt; 9 &lt;/span&gt;        &lt;span class="Identifier"&gt;pushl&lt;/span&gt;  %&lt;span class="Identifier"&gt;ebp&lt;/span&gt;
&lt;span class="lnr"&gt;10 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   %&lt;span class="Identifier"&gt;esp&lt;/span&gt;, %&lt;span class="Identifier"&gt;ebp&lt;/span&gt;
&lt;span class="lnr"&gt;11 &lt;/span&gt;        &lt;span class="Identifier"&gt;subl&lt;/span&gt;   $&lt;span class="Number"&gt;8&lt;/span&gt;, %&lt;span class="Identifier"&gt;esp&lt;/span&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
LEAVE instruction will set %esp to %ebp, then pop %ebp. It is the epilogue used for every function. Since the stack is intact in function f, we don't have to set %esp to %ebp, popping %ebp is enough. Compiler uses LEAVE instead of 2 instructions also for performance.&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt;15 &lt;/span&gt;        &lt;span class="Identifier"&gt;leave&lt;/span&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
As we can see, main characteristics of &lt;span style="color: #330099; font-style: italic;"&gt;__cdecl&lt;/span&gt; calling convention are:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Arguments are passed from right to left, and placed on the stack. &lt;/li&gt;
&lt;li&gt;Stack cleanup is performed by the caller. &lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
How about calling the function with &lt;span style="color: #330099; font-style: italic;"&gt;__stdcall&lt;/span&gt;?&lt;br /&gt;
&lt;pre&gt;&lt;span class="Type"&gt;int&lt;/span&gt; __attribute__((stdcall)) f(&lt;span class="Type"&gt;int&lt;/span&gt; a, &lt;span class="Type"&gt;int&lt;/span&gt; b)
{
&lt;span class="Statement"&gt;return&lt;/span&gt; a + b;
}
&lt;span class="Type"&gt;void&lt;/span&gt; test(&lt;span class="Type"&gt;void&lt;/span&gt;)
{
f(&lt;span class="Number"&gt;3&lt;/span&gt;, &lt;span class="Number"&gt;5&lt;/span&gt;);
}
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
The assembly for &lt;span style="color: #330099; font-style: italic;"&gt;__stdcall&lt;/span&gt; would be:&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Identifier"&gt;f&lt;/span&gt;:
&lt;span class="lnr"&gt; 2 &lt;/span&gt;        &lt;span class="Identifier"&gt;pushl&lt;/span&gt;  %&lt;span class="Identifier"&gt;ebp&lt;/span&gt;
&lt;span class="lnr"&gt; 3 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   %&lt;span class="Identifier"&gt;esp&lt;/span&gt;, %&lt;span class="Identifier"&gt;ebp&lt;/span&gt;
&lt;span class="lnr"&gt; 4 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   &lt;span class="Number"&gt;12&lt;/span&gt;(%&lt;span class="Identifier"&gt;ebp&lt;/span&gt;), %&lt;span class="Identifier"&gt;eax&lt;/span&gt;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;        &lt;span class="Identifier"&gt;addl&lt;/span&gt;   &lt;span class="Number"&gt;8&lt;/span&gt;(%&lt;span class="Identifier"&gt;ebp&lt;/span&gt;), %&lt;span class="Identifier"&gt;eax&lt;/span&gt;
&lt;span class="lnr"&gt; 6 &lt;/span&gt;        &lt;span class="Identifier"&gt;popl&lt;/span&gt;   %&lt;span class="Identifier"&gt;ebp&lt;/span&gt;
&lt;span class="lnr"&gt; 7 &lt;/span&gt;        &lt;span class="Identifier"&gt;ret&lt;/span&gt;    $&lt;span class="Number"&gt;8&lt;/span&gt;
&lt;span class="lnr"&gt; 8 &lt;/span&gt;&lt;span class="Identifier"&gt;test&lt;/span&gt;:
&lt;span class="lnr"&gt; 9 &lt;/span&gt;        &lt;span class="Identifier"&gt;pushl&lt;/span&gt;  %&lt;span class="Identifier"&gt;ebp&lt;/span&gt;
&lt;span class="lnr"&gt;10 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   %&lt;span class="Identifier"&gt;esp&lt;/span&gt;, %&lt;span class="Identifier"&gt;ebp&lt;/span&gt;
&lt;span class="lnr"&gt;11 &lt;/span&gt;        &lt;span class="Identifier"&gt;subl&lt;/span&gt;   $&lt;span class="Number"&gt;8&lt;/span&gt;, %&lt;span class="Identifier"&gt;esp&lt;/span&gt;
&lt;span class="lnr"&gt;12 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   $&lt;span class="Number"&gt;5&lt;/span&gt;, &lt;span class="Number"&gt;4&lt;/span&gt;(%&lt;span class="Identifier"&gt;esp&lt;/span&gt;)
&lt;span class="lnr"&gt;13 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   $&lt;span class="Number"&gt;3&lt;/span&gt;, (%&lt;span class="Identifier"&gt;esp&lt;/span&gt;)
&lt;span class="lnr"&gt;14 &lt;/span&gt;        &lt;span class="Identifier"&gt;call&lt;/span&gt;   &lt;span class="Identifier"&gt;f&lt;/span&gt;
&lt;span class="lnr"&gt;15 &lt;/span&gt;        &lt;span class="Identifier"&gt;subl&lt;/span&gt;   $&lt;span class="Number"&gt;8&lt;/span&gt;, %&lt;span class="Identifier"&gt;esp&lt;/span&gt;
&lt;span class="lnr"&gt;16 &lt;/span&gt;        &lt;span class="Identifier"&gt;leave&lt;/span&gt;
&lt;span class="lnr"&gt;17 &lt;/span&gt;        &lt;span class="Identifier"&gt;ret&lt;/span&gt;
&lt;/pre&gt;&lt;br /&gt;
The only difference from &lt;span style="color: #330099; font-style: italic;"&gt;__cdecl&lt;/span&gt; is that it uses "ret 8" (line 7) for self clean up stack. Therefore, the caller needs to "subl 8, %esp" (line 15) in order to retrieve %ebp back before using leave instruction.&lt;br /&gt;
&lt;br /&gt;
As we can see, main characteristics of &lt;span style="color: #330099; font-style: italic;"&gt;__stdcall&lt;/span&gt; calling convention are:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Arguments are passed from right to left, and placed on the stack. &lt;/li&gt;
&lt;li&gt;Stack cleanup is performed by the called function. &lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
And how about calling the function with &lt;span style="color: #330099; font-style: italic;"&gt;__fastcall&lt;/span&gt;?&lt;br /&gt;
&lt;pre&gt;&lt;span class="Type"&gt;int&lt;/span&gt; __attribute__((fastcall)) f(&lt;span class="Type"&gt;int&lt;/span&gt; a, &lt;span class="Type"&gt;int&lt;/span&gt; b)
{
&lt;span class="Statement"&gt;return&lt;/span&gt; a + b;
}
&lt;span class="Type"&gt;void&lt;/span&gt; test(&lt;span class="Type"&gt;void&lt;/span&gt;)
{
f(&lt;span class="Number"&gt;3&lt;/span&gt;, &lt;span class="Number"&gt;5&lt;/span&gt;);
}
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
The assembly generated by gcc for &lt;span style="color: #330099; font-style: italic;"&gt;__fastcall&lt;/span&gt; would be:&lt;br /&gt;
&lt;pre&gt;&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Identifier"&gt;f&lt;/span&gt;:
&lt;span class="lnr"&gt; 2 &lt;/span&gt;        &lt;span class="Identifier"&gt;pushl&lt;/span&gt;  %&lt;span class="Identifier"&gt;ebp&lt;/span&gt;
&lt;span class="lnr"&gt; 3 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   %&lt;span class="Identifier"&gt;esp&lt;/span&gt;, %&lt;span class="Identifier"&gt;ebp&lt;/span&gt;
&lt;span class="lnr"&gt; 4 &lt;/span&gt;        &lt;span class="Identifier"&gt;subl&lt;/span&gt;   $&lt;span class="Number"&gt;8&lt;/span&gt;, %&lt;span class="Identifier"&gt;esp&lt;/span&gt;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   %&lt;span class="Identifier"&gt;ecx&lt;/span&gt;, -&lt;span class="Number"&gt;4&lt;/span&gt;(%&lt;span class="Identifier"&gt;ebp&lt;/span&gt;)
&lt;span class="lnr"&gt; 6 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   %&lt;span class="Identifier"&gt;edx&lt;/span&gt;, -&lt;span class="Number"&gt;8&lt;/span&gt;(%&lt;span class="Identifier"&gt;ebp&lt;/span&gt;)
&lt;span class="lnr"&gt; 7 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   -&lt;span class="Number"&gt;8&lt;/span&gt;(%&lt;span class="Identifier"&gt;ebp&lt;/span&gt;), %&lt;span class="Identifier"&gt;eax&lt;/span&gt;
&lt;span class="lnr"&gt; 8 &lt;/span&gt;        &lt;span class="Identifier"&gt;addl&lt;/span&gt;   -&lt;span class="Number"&gt;4&lt;/span&gt;(%&lt;span class="Identifier"&gt;ebp&lt;/span&gt;), %&lt;span class="Identifier"&gt;eax&lt;/span&gt;
&lt;span class="lnr"&gt; 9 &lt;/span&gt;        &lt;span class="Identifier"&gt;leave&lt;/span&gt;
&lt;span class="lnr"&gt;10 &lt;/span&gt;        &lt;span class="Identifier"&gt;ret&lt;/span&gt;
&lt;span class="lnr"&gt;11 &lt;/span&gt;&lt;span class="Identifier"&gt;test&lt;/span&gt;:
&lt;span class="lnr"&gt;12 &lt;/span&gt;        &lt;span class="Identifier"&gt;pushl&lt;/span&gt;  %&lt;span class="Identifier"&gt;ebp&lt;/span&gt;
&lt;span class="lnr"&gt;13 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   %&lt;span class="Identifier"&gt;esp&lt;/span&gt;, %&lt;span class="Identifier"&gt;ebp&lt;/span&gt;
&lt;span class="lnr"&gt;14 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   $&lt;span class="Number"&gt;5&lt;/span&gt;, %&lt;span class="Identifier"&gt;edx&lt;/span&gt;
&lt;span class="lnr"&gt;15 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   $&lt;span class="Number"&gt;3&lt;/span&gt;, %&lt;span class="Identifier"&gt;ecx&lt;/span&gt;
&lt;span class="lnr"&gt;16 &lt;/span&gt;        &lt;span class="Identifier"&gt;call&lt;/span&gt;   &lt;span class="Identifier"&gt;f&lt;/span&gt;
&lt;span class="lnr"&gt;17 &lt;/span&gt;        &lt;span class="Identifier"&gt;popl&lt;/span&gt;   %&lt;span class="Identifier"&gt;ebp&lt;/span&gt;
&lt;span class="lnr"&gt;18 &lt;/span&gt;        &lt;span class="Identifier"&gt;ret&lt;/span&gt;
&lt;/pre&gt;&lt;br /&gt;
It indicates that the arguments should be placed in registers, rather than on the stack, whenever possible. The argument first argument 3 is placed in %ecx (line 15) and the second argument 5 is in %edx (line 14). Function f copy the arguments to its own stack, and calculate with the stack.&lt;br /&gt;
&lt;br /&gt;
What if calling a &lt;span style="color: #330099; font-style: italic;"&gt;__fastcall&lt;/span&gt; function more thatn two argument?&lt;br /&gt;
&lt;pre&gt;&lt;span class="Type"&gt;int&lt;/span&gt; __attribute__((fastcall)) f(&lt;span class="Type"&gt;int&lt;/span&gt; a, &lt;span class="Type"&gt;int&lt;/span&gt; b, &lt;span class="Type"&gt;int&lt;/span&gt; c)
{
&lt;span class="Statement"&gt;return&lt;/span&gt; a + b + c;
}
&lt;span class="Type"&gt;void&lt;/span&gt; test(&lt;span class="Type"&gt;void&lt;/span&gt;)
{
f(&lt;span class="Number"&gt;3&lt;/span&gt;, &lt;span class="Number"&gt;5&lt;/span&gt;, &lt;span class="Number"&gt;7&lt;/span&gt;);
}

&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Identifier"&gt;f&lt;/span&gt;:
&lt;span class="lnr"&gt; 2 &lt;/span&gt;        &lt;span class="Identifier"&gt;pushl&lt;/span&gt;  %&lt;span class="Identifier"&gt;ebp&lt;/span&gt;
&lt;span class="lnr"&gt; 3 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   %&lt;span class="Identifier"&gt;esp&lt;/span&gt;, %&lt;span class="Identifier"&gt;ebp&lt;/span&gt;
&lt;span class="lnr"&gt; 4 &lt;/span&gt;        &lt;span class="Identifier"&gt;subl&lt;/span&gt;   $&lt;span class="Number"&gt;8&lt;/span&gt;, %&lt;span class="Identifier"&gt;esp&lt;/span&gt;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   %&lt;span class="Identifier"&gt;ecx&lt;/span&gt;, -&lt;span class="Number"&gt;4&lt;/span&gt;(%&lt;span class="Identifier"&gt;ebp&lt;/span&gt;)
&lt;span class="lnr"&gt; 6 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   %&lt;span class="Identifier"&gt;edx&lt;/span&gt;, -&lt;span class="Number"&gt;8&lt;/span&gt;(%&lt;span class="Identifier"&gt;ebp&lt;/span&gt;)
&lt;span class="lnr"&gt; 7 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   -&lt;span class="Number"&gt;8&lt;/span&gt;(%&lt;span class="Identifier"&gt;ebp&lt;/span&gt;), %&lt;span class="Identifier"&gt;eax&lt;/span&gt;
&lt;span class="lnr"&gt; 8 &lt;/span&gt;        &lt;span class="Identifier"&gt;addl&lt;/span&gt;   -&lt;span class="Number"&gt;4&lt;/span&gt;(%&lt;span class="Identifier"&gt;ebp&lt;/span&gt;), %&lt;span class="Identifier"&gt;eax&lt;/span&gt;
&lt;span class="lnr"&gt; 9 &lt;/span&gt;        &lt;span class="Identifier"&gt;addl&lt;/span&gt;   &lt;span class="Number"&gt;8&lt;/span&gt;(%&lt;span class="Identifier"&gt;ebp&lt;/span&gt;), %&lt;span class="Identifier"&gt;eax&lt;/span&gt;
&lt;span class="lnr"&gt;10 &lt;/span&gt;        &lt;span class="Identifier"&gt;leave&lt;/span&gt;
&lt;span class="lnr"&gt;11 &lt;/span&gt;        &lt;span class="Identifier"&gt;ret&lt;/span&gt;    $&lt;span class="Number"&gt;4&lt;/span&gt;
&lt;span class="lnr"&gt;12 &lt;/span&gt;&lt;span class="Identifier"&gt;test&lt;/span&gt;:
&lt;span class="lnr"&gt;13 &lt;/span&gt;        &lt;span class="Identifier"&gt;pushl&lt;/span&gt;  %&lt;span class="Identifier"&gt;ebp&lt;/span&gt;
&lt;span class="lnr"&gt;14 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   %&lt;span class="Identifier"&gt;esp&lt;/span&gt;, %&lt;span class="Identifier"&gt;ebp&lt;/span&gt;
&lt;span class="lnr"&gt;15 &lt;/span&gt;        &lt;span class="Identifier"&gt;subl&lt;/span&gt;   $&lt;span class="Number"&gt;4&lt;/span&gt;, %&lt;span class="Identifier"&gt;esp&lt;/span&gt;
&lt;span class="lnr"&gt;16 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   $&lt;span class="Number"&gt;7&lt;/span&gt;, (%&lt;span class="Identifier"&gt;esp&lt;/span&gt;)
&lt;span class="lnr"&gt;17 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   $&lt;span class="Number"&gt;5&lt;/span&gt;, %&lt;span class="Identifier"&gt;edx&lt;/span&gt;
&lt;span class="lnr"&gt;18 &lt;/span&gt;        &lt;span class="Identifier"&gt;movl&lt;/span&gt;   $&lt;span class="Number"&gt;3&lt;/span&gt;, %&lt;span class="Identifier"&gt;ecx&lt;/span&gt;
&lt;span class="lnr"&gt;19 &lt;/span&gt;        &lt;span class="Identifier"&gt;call&lt;/span&gt;   &lt;span class="Identifier"&gt;f&lt;/span&gt;
&lt;span class="lnr"&gt;20 &lt;/span&gt;        &lt;span class="Identifier"&gt;subl&lt;/span&gt;   $&lt;span class="Number"&gt;4&lt;/span&gt;, %&lt;span class="Identifier"&gt;esp&lt;/span&gt;
&lt;span class="lnr"&gt;21 &lt;/span&gt;        &lt;span class="Identifier"&gt;leave&lt;/span&gt;
&lt;span class="lnr"&gt;22 &lt;/span&gt;        &lt;span class="Identifier"&gt;ret&lt;/span&gt;
&lt;/pre&gt;&lt;br /&gt;
The third argument 7 is pushed onto stack (line 16). And function f uses "ret 4" for cleaning up the stack. Therefore, we may conclude that main characteristics of &lt;span style="color: #330099; font-style: italic;"&gt;__stdcall&lt;/span&gt; calling convention are:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;The first two function arguments that require 32 bits or less are placed into registers ECX and EDX. &lt;/li&gt;
&lt;li&gt;The rest of them are pushed on the stack from right to left. &lt;/li&gt;
&lt;li&gt;If any stack based arguments were present, the callee cleans them off of the stack&lt;/li&gt;
&lt;/ol&gt;These simple examples are just for providing a basic idea of how these 3 calling convention work. For more detail, the followed links are suggested to read.&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/X86_calling_conventions"&gt;Wikipedia, "x86 calling convention"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://en.wikibooks.org/wiki/X86_Disassembly/Calling_Convention_Examples"&gt;WikiBooks, "x86 Disassembly/Calling Convention Examples"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://unixwiz.net/techtips/win32-callconv-asm.html"&gt;Steve Friedl, "Intel x86 Function-call Conventions - Assembly View"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.nynaeve.net/?p=66"&gt;Nynaeve, "Win32 calling conventions review"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.codeproject.com/KB/cpp/calling_conventions_demystified.aspx"&gt;Nemanja Trifunovic, CodeProject, "Calling Conventions Demystified"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/oldnewthing/archive/2004/01/02/47184.aspx"&gt;The Old New Thing, "The history of calling conventions, part 1"&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1626185782516232162-4112076658011844554?l=winfred-lu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://winfred-lu.blogspot.com/feeds/4112076658011844554/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1626185782516232162&amp;postID=4112076658011844554' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/4112076658011844554'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/4112076658011844554'/><link rel='alternate' type='text/html' href='http://winfred-lu.blogspot.com/2009/11/learning-x86-calling-conventions-by.html' title='Learning x86 Calling Conventions by Examples'/><author><name>Winfred</name><uri>http://www.blogger.com/profile/15649970719010644298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm2.static.flickr.com/1104/569054989_83809a02b2_m.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1626185782516232162.post-5604731131812620721</id><published>2009-11-08T23:08:00.000-08:00</published><updated>2011-12-25T21:02:18.126-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='loaders'/><category scheme='http://www.blogger.com/atom/ns#' term='nm'/><category scheme='http://www.blogger.com/atom/ns#' term='gcc'/><category scheme='http://www.blogger.com/atom/ns#' term='linking'/><category scheme='http://www.blogger.com/atom/ns#' term='c'/><category scheme='http://www.blogger.com/atom/ns#' term='linkers'/><title type='text'>Understand Weak Symbols by Examples</title><content type='html'>Wikipedia defines the weak symbols:  &lt;span style="font-style: italic;"&gt;"In computing, a weak symbol is a symbol definition in an object file or dynamic library that may be overridden by other symbol definitions, its value will be zero if no definition found by loader."&lt;/span&gt; In other words, we can define a symbol that doesn't need to be resolved at link time. It is a very well-known feature and used a lot in Linux Kernel, Glibc, and so on.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Take a look at the example, we are not able to compile it due to the 'undefined reference' error.&lt;br /&gt;
&lt;pre&gt;$ cat err.c
&lt;span class="Type"&gt;int&lt;/span&gt; main(&lt;span class="Type"&gt;void&lt;/span&gt;)
{
        f();
        &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Constant"&gt;0&lt;/span&gt;;
}

$ gcc err.c
/tmp/ccYx7WNg.o: In function `main':
err.c:(.text+0x12): undefined reference to `f'
collect2: ld returned 1 exit status&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Try to declare 'f' as an weak symbol, and we can compile it without error.&lt;br /&gt;
&lt;pre&gt;$ cat weak.c
&lt;span class="Type"&gt;void&lt;/span&gt; __attribute__((weak)) f();
&lt;span class="Type"&gt;int&lt;/span&gt; main(&lt;span class="Type"&gt;void&lt;/span&gt;)
{
        &lt;span class="Statement"&gt;if&lt;/span&gt; (f)
        f();
&lt;span class="Statement"&gt;        return&lt;/span&gt; &lt;span class="Constant"&gt;0&lt;/span&gt;;
}
$ gcc weak.c&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Note that the function 'f' is called inside an if statement. If not calling 'f' this way, we will get a 'Segmentation fault' error. In the weak.c example, 'f' is actually not invoked. It is because 'f' is an un-defined weak symbol and therefore will be zero when the loader cannot find it.&lt;br /&gt;
&lt;pre&gt;$ ./a.out
$ nm a.out
...
w f
08048324 T main
...&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Let's define the function 'f' in another file, and link the objects together. This time, 'f' will be correctly called. (Note that puts is the optimization of printf by gcc)&lt;br /&gt;
&lt;pre&gt;$ cat f.c
&lt;span class="PreProc"&gt;#include &lt;/span&gt;&lt;span class="Constant"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;
&lt;span class="Type"&gt;void&lt;/span&gt; f(&lt;span class="Type"&gt;void&lt;/span&gt;)
{
        printf(&lt;span class="Constant"&gt;"hello from f&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;);
}

$ gcc -c weak.c f.c
$ gcc -o weak weak.o f.o
$ ./weak
hello from f

$ nm weak.o
w f
00000000 T main
$ nm f.o
00000000 T f
U puts
$ nm weak
...
08048384 T f
08048354 T main
U puts@@GLIBC_2.0
...&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
We may even override the original weak symbol (type 'W') with a strong symbol (type 'T').&lt;br /&gt;
&lt;pre&gt;$ cat orig.c
&lt;span class="PreProc"&gt;#include &lt;/span&gt;&lt;span class="Constant"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;
&lt;span class="Type"&gt;void&lt;/span&gt; __attribute__((weak)) f()
{
        printf(&lt;span class="Constant"&gt;"original f..&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;);
}
&lt;span class="Type"&gt;int&lt;/span&gt; main(&lt;span class="Type"&gt;void&lt;/span&gt;)
{
        f();
&lt;span class="Statement"&gt;        return&lt;/span&gt; &lt;span class="Number"&gt;0&lt;/span&gt;;
}
$ gcc orig.c
$ ./a.out
original f..


$ cat ovrd.c
&lt;span class="PreProc"&gt;#include &lt;/span&gt;&lt;span class="Constant"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;
&lt;span class="Type"&gt;void&lt;/span&gt; f(&lt;span class="Type"&gt;void&lt;/span&gt;)
{
        printf(&lt;span class="Constant"&gt;"overridden f!&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;);
}
$ gcc -c orig.c ovrd.c
$ gcc -o ovrd orig.o ovrd.o
$ ./ovrd
overridden f!


$ nm orig.o
00000000 W f
00000014 T main
U puts
$ nm ovrd.o
00000000 T f
U puts
$ nm ovrd
...
0804838c T f
08048368 T main
U puts@@GLIBC_2.0
...&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
And of course, we can also override a weak object (type 'V') with a strong object (type 'D').&lt;br /&gt;
&lt;pre&gt;$ cat orig-obj.c
&lt;span class="PreProc"&gt;#include &lt;/span&gt;&lt;span class="Constant"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;
&lt;span class="Type"&gt;int&lt;/span&gt; __attribute__((weak)) x = &lt;span class="Number"&gt;1&lt;/span&gt;;
&lt;span class="Type"&gt;int&lt;/span&gt; __attribute__((weak)) y = &lt;span class="Number"&gt;1&lt;/span&gt;;
&lt;span class="Type"&gt;int&lt;/span&gt; main(&lt;span class="Type"&gt;void&lt;/span&gt;)
{
        printf(&lt;span class="Constant"&gt;"x = &lt;/span&gt;&lt;span class="Special"&gt;%d&lt;/span&gt;&lt;span class="Constant"&gt;, y = &lt;/span&gt;&lt;span class="Special"&gt;%d&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;, x, y);
&lt;span class="Statement"&gt;        return&lt;/span&gt; &lt;span class="Number"&gt;0&lt;/span&gt;;
}
$ gcc orig-obj.c
$ ./a.out
x = 1, y = 1


$ cat ovrd-obj.c
&lt;span class="Type"&gt;int&lt;/span&gt; x = &lt;span class="Number"&gt;2&lt;/span&gt;;
&lt;span class="Type"&gt;void&lt;/span&gt; f(&lt;span class="Type"&gt;void&lt;/span&gt;)
{
}
$ gcc -c orig-obj.c ovrd-obj.c
$ gcc -o ovrd-obj orig-obj.o ovrd-obj.o
$ ./ovrd-obj
x = 2, y = 1


$ nm orig-obj.o
00000000 T main
U printf
00000000 V x
00000004 V y
$ nm ovrd-obj.o
00000000 T f
00000000 D x
$ nm ovrd-obj
...
08048394 T f
08048354 T main
U printf@@GLIBC_2.0
080495c8 D x
080495c4 V y
...&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
What if there are multiple symbols? Linker's symbol rules tell us that:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Multiple strong symbols are not allowed&lt;/li&gt;
&lt;li&gt;Given a strong symbol and multiple weak symbols --&amp;gt;  choose the strong symbol&lt;/li&gt;
&lt;li&gt;Given multiple weak symbols --&amp;gt; choose any of those weak symbols&lt;br /&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
&lt;pre&gt;$ cat mul.c
&lt;span class="Type"&gt;int&lt;/span&gt; main(&lt;span class="Type"&gt;void&lt;/span&gt;)
{
        f();
&lt;span class="Statement"&gt;        return&lt;/span&gt; &lt;span class="Number"&gt;0&lt;/span&gt;;
}
$ cat s1.c
&lt;span class="PreProc"&gt;#include &lt;/span&gt;&lt;span class="Constant"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;
&lt;span class="Type"&gt;void&lt;/span&gt; f(&lt;span class="Type"&gt;void&lt;/span&gt;)
{
        printf(&lt;span class="Constant"&gt;"1st strong f from &lt;/span&gt;&lt;span class="Special"&gt;%s&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;, &lt;span class="Constant"&gt;__FILE__&lt;/span&gt;);
}
$ cat s2.c
&lt;span class="PreProc"&gt;#include &lt;/span&gt;&lt;span class="Constant"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;
&lt;span class="Type"&gt;void&lt;/span&gt; f(&lt;span class="Type"&gt;void&lt;/span&gt;)
{
        printf(&lt;span class="Constant"&gt;"2nd strong f from &lt;/span&gt;&lt;span class="Special"&gt;%s&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;, &lt;span class="Constant"&gt;__FILE__&lt;/span&gt;);
}
$ cat w1.c
&lt;span class="PreProc"&gt;#include &lt;/span&gt;&lt;span class="Constant"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;
&lt;span class="Type"&gt;void&lt;/span&gt; __attribute__((weak)) f(&lt;span class="Type"&gt;void&lt;/span&gt;)
{
        printf(&lt;span class="Constant"&gt;"1st weak f from &lt;/span&gt;&lt;span class="Special"&gt;%s&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;, &lt;span class="Constant"&gt;__FILE__&lt;/span&gt;);
}
$ cat w2.c
&lt;span class="PreProc"&gt;#include &lt;/span&gt;&lt;span class="Constant"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;
&lt;span class="Type"&gt;void&lt;/span&gt; __attribute__((weak)) f(&lt;span class="Type"&gt;void&lt;/span&gt;)
{
        printf(&lt;span class="Constant"&gt;"2nd weak f from &lt;/span&gt;&lt;span class="Special"&gt;%s&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;, &lt;span class="Constant"&gt;__FILE__&lt;/span&gt;);
}
$ gcc -c mul.c s1.c s2.c w1.c w2.c


$ gcc -o test1 mul.o s1.o s2.o
s2.o: In function `f':
s2.c:(.text+0x0): multiple definition of `f'
s1.o:s1.c:(.text+0x0): first defined here
collect2: ld returned 1 exit status


$ gcc -o test2 mul.o s1.o w1.o w2.o
$ ./test2
1st strong f from s1.c


$ gcc -o test3-1 mul.o w1.o w2.o
$ ./test3-1
1st weak f from w1.c
$ gcc -o test3-2 mul.o w2.o w1.o
$ ./test3-2
2nd weak f from w2.c&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Hope these examples help!&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Weak_symbol"&gt;&lt;/a&gt;&lt;a href="http://en.wikipedia.org/wiki/Weak_symbol"&gt;Wikipedia, "Weak Symbol"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.embedded-bits.co.uk/tag/weak-symbols/"&gt;Embedded Bits, "Digging Deepter into Weak Symbols"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Function-Attributes.html"&gt;gcc manual, "Declaring Attributes of Functions"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://sourceware.org/binutils/docs/binutils/nm.html"&gt;binutil Document, "nm"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.slideshare.net/satpalparmar/linkers-and-loaders-presentation"&gt;Sandeep Grover, "Linkers &amp;amp; Loaders - A Programmers Perspective"&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1626185782516232162-5604731131812620721?l=winfred-lu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://winfred-lu.blogspot.com/feeds/5604731131812620721/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1626185782516232162&amp;postID=5604731131812620721' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/5604731131812620721'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/5604731131812620721'/><link rel='alternate' type='text/html' href='http://winfred-lu.blogspot.com/2009/11/understand-weak-symbols-by-examples.html' title='Understand Weak Symbols by Examples'/><author><name>Winfred</name><uri>http://www.blogger.com/profile/15649970719010644298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm2.static.flickr.com/1104/569054989_83809a02b2_m.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1626185782516232162.post-9051169707114605097</id><published>2008-08-21T02:02:00.000-07:00</published><updated>2010-03-31T20:05:18.492-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='debian'/><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='backport'/><title type='text'>Debian Backporting</title><content type='html'>It is easy to install packages on Debian. All you have to do is "apt-get install package". But what if we would like to install a newer version package? For example, git-core version on Debian stable is 1.4.4. It is too old and does not have basic commands such as git config, init,... etc. We may install git from Debian Backports. It is a easier way than building from source for most people.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;add the backport mirrors to /etc/apt/sources.list&lt;br /&gt;
&lt;span style="font-style: italic; color: rgb(51, 51, 153);"&gt;deb http://ftp.tw.debian.org/backports.org/ etch-backports main non-free&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic; color: rgb(51, 51, 153);"&gt;deb-src http://ftp.tw.debian.org/backports.org/ etch-backports main non-free&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;import backports.org archive's key into apt&lt;br /&gt;
&lt;span style="font-style: italic; color: rgb(51, 51, 153);"&gt;# apt-get install debian-backports-keyring&lt;br /&gt;
(or # wget -O - http://backports.org/debian/archive.key | apt-key add -)&lt;br /&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;resynchronize the package index files from their sources&lt;br /&gt;
&lt;span style="font-style: italic; color: rgb(51, 51, 153);"&gt;# apt-get update&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;remove previously installed git&lt;br /&gt;
&lt;span style="font-style: italic; color: rgb(51, 51, 153);"&gt;# apt-get remove git-core&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;install git from&lt;br /&gt;
&lt;span style="font-style: italic; color: rgb(51, 51, 153);"&gt;# apt-get -t etch-backports install git-core&lt;br /&gt;
(or # aptitude -t etch-backports install "git-core")&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;finish&lt;br /&gt;
&lt;span style="font-style: italic; color: rgb(51, 51, 153);"&gt;# git --version&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic; color: rgb(51, 51, 153);"&gt;git version 1.5.6.3&lt;/span&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;/ol&gt;We have git 1.5.6.3 installed. Then, happily coding. :P&lt;br /&gt;
For more information, take a look at &lt;a href="http://www.backports.org/dokuwiki/doku.php?id=instructions"&gt;Debian Backports wiki&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1626185782516232162-9051169707114605097?l=winfred-lu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://winfred-lu.blogspot.com/feeds/9051169707114605097/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1626185782516232162&amp;postID=9051169707114605097' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/9051169707114605097'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/9051169707114605097'/><link rel='alternate' type='text/html' href='http://winfred-lu.blogspot.com/2008/08/debian-backporting.html' title='Debian Backporting'/><author><name>Winfred</name><uri>http://www.blogger.com/profile/15649970719010644298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm2.static.flickr.com/1104/569054989_83809a02b2_m.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1626185782516232162.post-3811888781241557816</id><published>2008-08-20T02:53:00.000-07:00</published><updated>2010-03-31T20:06:03.045-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mips'/><category scheme='http://www.blogger.com/atom/ns#' term='uboot'/><category scheme='http://www.blogger.com/atom/ns#' term='as'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly'/><title type='text'>Remove allow_branch_to_undefined from U-boot</title><content type='html'>Old U-boot (v1.1.3 in my example, too old hum?) needs a option -mips_allow_branch_to_undefined for ELDK AS to assemble. We have to modify cpu/mips/start.S so that AS of other toolchains could assemble it without an error - Error: can't resolve `_GLOBAL_OFFSET_TABLE_' {*UND* section} - `L16' {.text section}&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
original start.S:&lt;br /&gt;
&lt;pre&gt;/* Initialize GOT pointer.
*/
bal     1f
nop
.word   _GLOBAL_OFFSET_TABLE_ - 1f + 4
1:
move    gp, ra
lw      t1, 0(ra)
add     gp, t1
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
It counts an offset first, and gets the gp later from the return address and the offset. Let us do it with different method.&lt;br /&gt;
&lt;br /&gt;
new start.S:&lt;br /&gt;
&lt;pre&gt;bal     1f
nop
.word   _GLOBAL_OFFSET_TABLE_
1:
lw      gp, 0(ra)
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Second, remove -Wa,-mips_allow_branch_to_undefined from cpu/mips/config.mk. Then we can make Uboot successfully with the toolchain built from buildroot.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1626185782516232162-3811888781241557816?l=winfred-lu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://winfred-lu.blogspot.com/feeds/3811888781241557816/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1626185782516232162&amp;postID=3811888781241557816' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/3811888781241557816'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/3811888781241557816'/><link rel='alternate' type='text/html' href='http://winfred-lu.blogspot.com/2008/08/remove-allowbranchtoundefined-from-u.html' title='Remove allow_branch_to_undefined from U-boot'/><author><name>Winfred</name><uri>http://www.blogger.com/profile/15649970719010644298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm2.static.flickr.com/1104/569054989_83809a02b2_m.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1626185782516232162.post-3782743942130684940</id><published>2008-08-11T17:30:00.000-07:00</published><updated>2010-03-31T20:12:44.274-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='car'/><title type='text'>交車需知大全</title><content type='html'>&lt;span style="font-weight: normal;font-size:100%;" &gt;前陣子買車前到處爬文整理起來的交車需知大全，本來一直放在googole docs沒公開，剛看到有直接張貼到blogger的功能，拿來試用看看，有興趣的人可以拿來參考...  :)&lt;/span&gt;&lt;p&gt;&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h2&gt;一、基本需知&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;交車一定要選在大白天，晚上會看不清楚車輛烤漆和內裝的瑕疵&lt;/li&gt;
&lt;li&gt;不選在下午四、五點交車，因為員工趕著下班。&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;h2&gt;二、證件核對&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;詳細核對契約書內容，業代贈品是否符合。點交所有車籍證件是否正確齊全，稅單發票等等都不可少&lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;檢驗合格證：&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;該份資料為商檢局做汽車品質的測試證明單。&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;貨物稅完稅證明、發票、牌照稅及燃料稅單：&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;這些稅單代表新出廠的車輛完全沒有問題，可上路，是否納清，請核對。&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;出廠證明書、海關進口證明書：&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;證明書內明有生產日期、汽車年份、生產地，而且有海關進口書，其中會標示產地國、生產日期....等資料，為汽車進口重要資料。&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;牌照申請書：&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;該份資料是日後所有權轉移，變更地址申請等車籍原始資料，到監理處所要用，要保管好。如發生遺失，馬上到監理所申請補發。不然車子被過戶也不知道。&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;行照及保險卡：&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;行照內記載有牌照號碼、型式、顏色、引擎及車身號碼等資料，要確認該份資料與車是否相符，&lt;/li&gt;
&lt;li&gt;核對行照車主，地址是否有錯誤。&lt;/li&gt;
&lt;li&gt;原發照日期和換補照日期是否相同、有效日期(應為三年)、指定檢驗日期(應為五年)&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;保險卡的核對工作主要有車主、 車號、車子種類。保險種類、自付額多少等資料，與當初承保條件有無相 符&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;車籍資料袋：&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;每輛車的車籍資料袋內另附說明書、保養手冊說明保養須知，各地服務廠商地點、電話。&lt;/li&gt;
&lt;li&gt;尤其是保證書部份，要看清楚保證內容是否公平，其範圍為 何，保證幾年幾萬公里，不在保證之列的零件就要小心檢查狀況。&lt;/li&gt;
&lt;li&gt;記得是向那位業務員買車，有問題馬上通知業 務員，切忌懷有省事事省的駝鳥心態，等到小毛病變大毛病&lt;/li&gt;
&lt;li&gt;車主手冊、保養手冊(有無經銷商蓋章)、點煙器(這個通常會隨車主手冊一起領取)&lt;/li&gt;
&lt;/ul&gt;&lt;/ul&gt;&lt;br /&gt;
&lt;h2&gt;三、車況檢查&lt;br /&gt;
&lt;/h2&gt;&lt;h3&gt;引擎室&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;引擎蓋&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;與二邊前葉子鈑的間隙是否平均，如果沒有可以請技師當場調整。&lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;開啟和關閉是否容易操作，順便請技師幫新手介紹一下簡易保養的重點部位，並瞭解一下車身號碼和引擎號碼的標示處。&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;油箱蓋&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;開啟和關閉是否容易操作，免得萬一因為沒辦法開啟加油叨在路上，那會粉臭哩&lt;/li&gt;
&lt;li&gt;當然也可以請業代事先在交車前幫泥加滿油(可對發票來核準)&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;檢查五油三水是否充足，有無漏油(水)，冷卻水是否有添加防鏽劑&lt;/li&gt;
&lt;li&gt;檢查各油、水箱的開關及錶狀況是否 良好&lt;/li&gt;
&lt;li&gt;再檢查各管路導線是否固定在定位，引擎皮帶(充電馬達同)風扇皮帶作用是否良好&lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;五油&lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;ul&gt;&lt;li&gt;機油&lt;br /&gt;
機油量標準量法：將車停放平坦路面，拉起手煞車，關掉引擎，並等待數分鐘，讓機油流回油底殼。取出油尺，並用清潔的布拭乾淨。插回油尺，且要完全放到底。再次取出油尺，正常的油位高度必須在油尺上的Ｍａｘ與Ｍｉｎ兩個記號之間。&lt;/li&gt;
&lt;li&gt;變速箱油&lt;br /&gt;
自排油量標準量法：發動引擎，讓車行駛，使水溫表指針達到正常工作溫度；將車停放平坦路面，拉起手煞車（不可關掉引擎）。引擎繼續怠速運轉，腳踩煞車踏 板；將排檔桿從Ｐ檔位逐一換至Ｌ檔位，並在各檔位停留數秒鐘。最後將排檔桿排在P檔位。取出油尺，並用清潔的布拭乾淨。插回油尺，且要完全放到底。再次取 出油尺，正常的油位高度必須在油尺上HOT範圍內。&lt;/li&gt;
&lt;li&gt;動力方向機油&lt;br /&gt;
動力方向機油量標準量法：將車停放平坦路面，拉起手煞車，取出油尺，並用清潔的布拭乾淨。插回油尺，且要完全放到底。再次取出油尺，正常的油位高度必須在油尺上HOT範圍內。&lt;/li&gt;
&lt;li&gt;煞車油&lt;br /&gt;
煞車油是最重要的一種油，依照規定通常一年或三萬公里更換一次（以先到者為準），若還未到更換時機，也要檢視煞車油存量，您可先由煞車油壺外的刻度判別，煞車油必須介於Ｍａｘ與Ｍｉｎ之間，若有減少一定要添加至Ｍax的位置，而號數不同的煞車油更是不可混用。&lt;/li&gt;
&lt;li&gt;汽油&lt;br /&gt;
行車上路前一定要檢查汽油量是否充足。&lt;/li&gt;
&lt;/ul&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;四壓&lt;/li&gt;
&lt;ul&gt;&lt;li&gt; 油壓&lt;br /&gt;
機油壓力指示燈因在鎖匙開紅火時亮(未亮請進廠做進一步的檢修。)，引擎發動後十秒內熄滅，如未在十秒內熄滅請馬上熄火，檢查機油量。如充足請請進廠做進一步的檢修。(若在行駛途中亮起時，請馬上找地方停下來，看一下油尺，檢查機油量是否足夠，不夠時一定要加足。)&lt;/li&gt;
&lt;li&gt;電壓&lt;br /&gt;
電瓶指示燈因在鎖匙開紅火時亮(未亮請進廠做進一步的檢修。)，引擎發動後十秒內熄滅，如未在十秒內熄滅請進廠做進一步的檢修。&lt;/li&gt;
&lt;li&gt;胎壓&lt;br /&gt;
每日行車前應檢查全部輪胎胎壓是否正常(一般車輛在車門柱上或手套箱內有胎壓指示表)&lt;/li&gt;
&lt;li&gt;氣壓(真空輔助)&lt;br /&gt;
將煞車踏板踏死後起動引擎看踏板踏是否會下沉，若煞車踏板會下沉即表示真空輔助煞車作用正常，若沒下沉車主可將煞車總泵輔助器上有一條從進氣岐管接至煞車總泵輔助器的黑色軟管檢查是否有無真空作用，老舊破裂，阻塞，若沒有以上的徵狀請進廠做進一步的檢修。&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;三水&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;ul&gt;&lt;li&gt;水箱水&lt;br /&gt;
水箱中的液體為水與水箱精，平時應常檢查水箱及副水箱內的儲水量是否足夠，如果副水箱的水位有降低，應在冷車時以清水或水箱精加至上限與下限的中間即可， 若要自我檢視水箱的儲水量，請不要在引擎運轉時或停止運轉一小時內打開水箱?#092;，以免因高溫的水箱水噴出而被燙傷。&lt;/li&gt;
&lt;li&gt; 電瓶水&lt;br /&gt;
電瓶水的部份，一樣有注水的上、下限，不足時請以純水或電瓶水填加，切勿添加自來水。&lt;/li&gt;
&lt;li&gt;雨刷水&lt;br /&gt;
雨刷水也是需要經常檢查水位是否足夠，雨刷水最好能添加一些能夠去除擋風玻璃上的油漬之清潔液，以普通的清水代替也可，雨刷水不足雖然不會讓車輛故障，但擋風玻璃被前車噴到的髒污無法及時清除，也是有可能會影響行車安全。&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/ul&gt;&lt;br /&gt;
&lt;h3&gt;外觀&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;車燈&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;檢查所以燈泡是否都會亮，玻璃是否有破損，燈殼是否有破損或水氣。&lt;/li&gt;
&lt;li&gt;前方：方向燈、前小燈、大燈、、遠光燈閃動、遠光燈固定、暫停雙黃閃燈、霧燈測試&lt;br /&gt;
車側：側方向燈&lt;br /&gt;
後方：方向燈、後小燈、煞車燈、暫停雙黃閃燈、後霧燈(如果有的話)、第三煞車燈、倒車燈測試試&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;若可以，試一下大燈照出去的位置是否太高或太低&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;輪胎&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;輪胎胎壓正常與否。&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;車門&lt;br /&gt;
&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;電動後視鏡，折疊或調整是否正常。&lt;/li&gt;
&lt;li&gt;試開關每一個車門是否開關順暢，關上時有無異音。&lt;/li&gt;
&lt;li&gt;測試後行李箱蓋開啟和關閉是否容易操作，並檢查與車體的間隙是否平均正常。&lt;/li&gt;
&lt;li&gt;檢查車門膠條等是否安裝妥當、車門與車體接縫處是否均勻、車門邊的板金烤漆是否均勻。&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;車窗&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;電動窗及天窗開啟上掀等動作是否上下正常，有無異音產生。&lt;/li&gt;
&lt;li&gt;玻璃與窗框接縫是否密合&lt;/li&gt;
&lt;li&gt;前後雨刷的各項測試如間歇雨刷功能、正常速及快速雨刷功能、噴水測試，有後檔雨刷配置的車款，也要做後雨刷功能測試。&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;車身&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;站在離車身3公尺遠的地方，檢查車身烤漆顏色是否有色差，觀察車輛塗裝(噴漆)是否良好&lt;/li&gt;
&lt;li&gt;版件組裝是否平順，然後貼近車身，看烤漆是否平順或刮傷，有無流汗或顆粒(可用手撫摸)&lt;/li&gt;
&lt;li&gt;車身飾條邊及裝潢部份是否完整，有沒有劃破銬漆屑，接縫處是否生鏽起泡。&lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;檢查車底是否有生鏽&lt;/li&gt;
&lt;li&gt;有無組裝產生的傷痕或割痕，尤其是你有外加配件，小心技師不小心傷到烤漆保桿等等。&lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;如果是有買天窗的車款，可做天窗漏水測試(時間建議至少數分鐘，可以由人員用水管不停的灑水於天窗上測試之)。&lt;/li&gt;
&lt;/ul&gt;&lt;/ul&gt;&lt;br /&gt;
&lt;h3&gt;內裝&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;組裝：&lt;br /&gt;
&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;門板是否牢靠，方向盤、排檔桿、門把、門飾板是否有污損&lt;/li&gt;
&lt;li&gt;ABCD柱的塑料鈑件平整度是否正常，各鈑件角落的修邊是否會過於銳利有可能傷到人。&lt;/li&gt;
&lt;li&gt;檢視車內組裝是否平順，塑膠件有無毛邊或突起，車內頂棚是否髒舊或破損&lt;/li&gt;
&lt;li&gt;裝配是否完整，如石英鐘、除霧線、毛毯、椅套是否短缺。&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;車門&lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;ul&gt;&lt;li&gt;各個車門的開啟是否順暢無雜音，與車身鈑金件的間隙是否平均正常。&lt;/li&gt;
&lt;/ul&gt;&lt;/ul&gt;&lt;ul&gt;&lt;ul&gt;&lt;li&gt;兒童安全鎖的測試&lt;/li&gt;
&lt;li&gt;喇叭外罩與車門飾板是否安裝妥當、有無瑕疵&lt;/li&gt;
&lt;li&gt;隔熱紙氣泡檢查&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;安全帶&lt;br /&gt;
&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;安全帶扣上是否順暢。上下調整是否正常。&lt;/li&gt;
&lt;li&gt;拉扯安全帶，看看接縫處是否密實。&lt;/li&gt;
&lt;li&gt;檢查安全帶上的生產日期，不可和車籍登記的出廠日期相差超過3個月，以免買到庫存車&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;踏板&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;踩踏各板(油門、剎車、離合器)作用是否良好，是否順暢，鬆緊度與本身習慣差太多時，可請技工調整符合自己的高度。&lt;/li&gt;
&lt;li&gt; 腳踏墊是否完整無缺，另購踏墊者是否附上原廠踏墊。&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;中控&lt;br /&gt;
&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;拉手煞車拉桿，是否正常（參考路試）&lt;/li&gt;
&lt;li&gt;照明燈、各項行車警示燈、燈光亮度可調開關、室內燈各段測試(包含開車門、開關門的燈光延遲設計、閱讀燈、地板照明燈(有配備時)&lt;/li&gt;
&lt;li&gt;檢查各儀表作用是否正常，儀表版燈號是否正常，再檢查開動車門窗、雨刷、中央控鎖、電動窗、車窗把手。&lt;/li&gt;
&lt;li&gt;電動後視鏡折疊、開關是否正常，有無異音。&lt;/li&gt;
&lt;li&gt;空調系統功能是否正常，視察冷氣作用及各段強度如何，各出風口作用是否正常。冷氣使用後，車內是否會漏水(冷凝管排水不良會漏水)車內如長期滴水，底盤鏽蝕。&lt;/li&gt;
&lt;li&gt;音響功能是否良好正常。cd(dvd)是否挑片，收音機有無接收不良，轉台時是否會跳台。車內四(二、六)個音響喇叭是否正常，前後左右試看看。&lt;/li&gt;
&lt;li&gt;手套箱開關測試，中央置物拖盤開合測試&lt;/li&gt;
&lt;li&gt;點煙器功能測試，行李箱12V電源插座測試&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;方向盤&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;ul&gt;&lt;li&gt;方向盤上下(前後)調整是否正常。&lt;/li&gt;
&lt;li&gt;雨刷開關，每一段都測試，噴水這項也不要忘了。&lt;/li&gt;
&lt;li&gt;若可以，測試一下除霧線，有無被貼隔熱紙廠商給切斷。&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;後車廂&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;檢查備胎是否穩固，換胎工具是否完備&lt;/li&gt;
&lt;li&gt;備胎蓋、後檔玻璃開關是否正常&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;座椅&lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;ul&gt;&lt;li&gt;駕駛座高低調整，所有座椅前後調整，椅背角度調整，是否生鏽或產生異音。&lt;/li&gt;
&lt;li&gt;把每一項平放或躺平方式、後座坐椅的折疊動作都測過一遍。&lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;皮椅或布椅的平整度，是否乾淨和縫線有無脫落現象，有無外傷或瑕疵。&lt;/li&gt;
&lt;li&gt;頭枕是否可正常調整。&lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;前後座椅扶手。&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/ul&gt;&lt;br /&gt;
&lt;h3&gt;其他&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;看里程數顯示&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;新車里程數正常約10～30公里，向外縣市調車大約50～60公里，最高不應超過80公里&lt;/li&gt;
&lt;li&gt;若超過此數，就要詳細探查原因，若是車廠自身不斷試車，增加里程數，則顯示該車或有部分故障，須不斷試車維修&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;遙控器及防盜功能測試&lt;/li&gt;
&lt;li&gt;Keyless測試&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;車用免持通訊系統測試&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;h2&gt;四、路試&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;把音響關掉&lt;/li&gt;
&lt;li&gt;正式做路試前，請輕加油門，再踩煞車試試，確認煞車功能運作正常。&lt;/li&gt;
&lt;li&gt;手煞車測試，可以試試拉起手煞車，並將排檔放在D檔測試有無滑動，尤其在上坡路。&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;慢慢拉聽有幾格聲音，應該要有7～9聲&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;先找個空曠安全的地方&lt;/li&gt;
&lt;li&gt;瞭解一下愛車的煞車制動力表現。有ABS配置的車款，不用客氣，加速到時速六、七十公里，用力的踩下煞車吧…對 粉多沒有使用ABS的車主來講，這會是個寶貴的使用經驗。當然，通常會由交車人員陪同測試，這時務必確認車上乘員都有綁安全帶，並告知即將做的煞車各項測 試。&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;由最低檔往上順序排檔，注意聽聽看有沒有異常的聲音，順便瞭解一下檔位的排法。完成後可以做KICKDOWN強迫降檔測試、OD檔切換開關的變速箱反應觀察。&lt;/li&gt;
&lt;li&gt;找路況稍有不平的地方讓車輪壓過去，仔細聽聽有無異常的聲音傳來。&lt;/li&gt;
&lt;li&gt;找個地方做U型迴轉，試著把方向盤打到接近頂點(不能再轉動的地方再退一點點)讓車子做U型迴轉，聽看看傳動軸有沒有異常的聲音傳來。&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1626185782516232162-3782743942130684940?l=winfred-lu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://winfred-lu.blogspot.com/feeds/3782743942130684940/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1626185782516232162&amp;postID=3782743942130684940' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/3782743942130684940'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/3782743942130684940'/><link rel='alternate' type='text/html' href='http://winfred-lu.blogspot.com/2008/08/blog-post.html' title='交車需知大全'/><author><name>Winfred</name><uri>http://www.blogger.com/profile/15649970719010644298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm2.static.flickr.com/1104/569054989_83809a02b2_m.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1626185782516232162.post-6377088419955215406</id><published>2008-07-29T22:06:00.000-07:00</published><updated>2010-03-31T20:07:24.721-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='TR-069'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenACS'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='jdbc'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>OpenACS Configuration</title><content type='html'>&lt;ol&gt;&lt;li&gt;Install JDK&lt;br /&gt;
&lt;span style="color: rgb(102, 0, 0); font-style: italic;"&gt;# apt-get install sun-java5-jdk&lt;/span&gt;&lt;/li&gt;

&lt;li&gt;Install mysql&lt;br /&gt;
&lt;span style="color: rgb(102, 0, 0); font-style: italic;"&gt;# apt-get install mysql-server&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ol start="3"&gt;&lt;li&gt;&lt;span style="color: rgb(102, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Install Java database (JDBC) driver&lt;br /&gt;
&lt;span style="font-style: italic; color: rgb(102, 0, 0);"&gt;# apt-get install libmysql-java&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 0, 0); font-style: italic;"&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Setting up the user to use JDBC&lt;br /&gt;
&lt;span style="font-style: italic; color: rgb(102, 0, 0);"&gt;# export CLASSPATH=$CLASSPATH:/usr/share/java/mysql.jar&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Install JBOSS (&lt;a href="http://labs.jboss.com/file-access/default/members/jbossas/freezone/docs/Installation_Guide/beta500/html-single/index.html"&gt;JBOSS installation guide&lt;/a&gt;) either way:&lt;br /&gt;
a) download and unzip &lt;a href="http://downloads.sourceforge.net/jboss/jboss-4.2.3.GA.zip?modtime=1216412104&amp;amp;big_mirror=1"&gt;jboss-4.2.3-GA.zip&lt;/a&gt;&lt;br /&gt;
b) download &lt;a href="http://downloads.sourceforge.net/jboss/jboss-4.2.3.GA-src.tar.gz?modtime=1216412028&amp;amp;big_mirror=1"&gt;jboss-4.2.3-GA-src.tar.gz&lt;/a&gt; and built it using Apache ANT&lt;br /&gt;
c) use &lt;a href="https://sourceforge.net/project/showfiles.php?group_id=22866&amp;amp;package_id=193295"&gt;jems-installer&lt;/a&gt;:&lt;br /&gt;
&lt;span style="font-style: italic; color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(102, 0, 0);"&gt;#  java  -jar jems-installer-1.2.1.CR4.jar&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Test the JBOSS installation&lt;br /&gt;
&lt;span style="font-style: italic; color: rgb(102, 0, 0);"&gt;# run.sh&lt;/span&gt;&lt;br /&gt;
Make sure the followed:&lt;br /&gt;
a) $JBOSS_HOME, $PATH are correctly configured in bashrc file&lt;br /&gt;
b) /etc/hostname can be correctly resolved&lt;br /&gt;
&lt;span style="color: rgb(102, 102, 0);"&gt;$JBOSS_HOME/server/default/log would be helpful to see what's wrong with the configurations&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Make sure JDBC driver mysql-connector-java.jar is located in $JBOSS_HOME/server/default/lib&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Download and unpack &lt;a href="http://downloads.sourceforge.net/openacs/openacs-bin-0.02.zip?modtime=1213560821&amp;amp;big_mirror=0"&gt;OpenACS binary&lt;/a&gt;&lt;br /&gt;
&lt;span style="font-style: italic; color: rgb(102, 0, 0);"&gt;# unzip openacs-bin-0.02.zip&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Create an mysql account and database for OpenACS&lt;br /&gt;
&lt;span style="font-style: italic; color: rgb(102, 0, 0);"&gt;# mysql -p&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic; color: rgb(102, 0, 0);"&gt; mysql&gt; create database ACS;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic; color: rgb(102, 0, 0);"&gt;mysql&gt; grant all on ACS.* to openacs_user identified by ‘openacs_pw’&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Deploy OpenACS&lt;br /&gt;
&lt;span style="font-style: italic; color: rgb(102, 0, 0);"&gt;# cp openacs/openacs-ds.xml $JBOSS_HOME/server/default/deploy/&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic; color: rgb(102, 0, 0);"&gt;# cp openacs/acs.ear $JBOSS_HOME/server/default/deploy/&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic; color: rgb(102, 0, 0);"&gt;# cp openacs/openacs-service.xml $JBOSS_HOME/server/default/deploy/jms/&lt;/span&gt;&lt;br /&gt;
Modify connection-url, user-name, password in openacs-ds.xml&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Run JBOSS&lt;br /&gt;
&lt;span style="font-style: italic; color: rgb(102, 0, 0);"&gt;# run.sh&lt;/span&gt;&lt;br /&gt;
Disable JBOSS &lt;span style="color: rgb(102, 102, 0);"&gt;CREATE_TABLES_ON_STARTUP&lt;/span&gt; if getting an error "java.sql.SQLException: Table already exists"&lt;br /&gt;
file: &lt;span style="color: rgb(102, 102, 0);"&gt;$JBOSS_HOME/server/default/deploy/jms/hsqldb-jdbc2-service.xml&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Web interface is accessible at http://your.server.ip:8080/openacs/index.jsf.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1626185782516232162-6377088419955215406?l=winfred-lu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://winfred-lu.blogspot.com/feeds/6377088419955215406/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1626185782516232162&amp;postID=6377088419955215406' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/6377088419955215406'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/6377088419955215406'/><link rel='alternate' type='text/html' href='http://winfred-lu.blogspot.com/2008/07/openacs-configuration.html' title='OpenACS Configuration'/><author><name>Winfred</name><uri>http://www.blogger.com/profile/15649970719010644298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm2.static.flickr.com/1104/569054989_83809a02b2_m.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1626185782516232162.post-7410080265696831621</id><published>2008-07-17T01:12:00.000-07:00</published><updated>2010-03-31T20:08:45.015-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='inotify'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='filesystem'/><category scheme='http://www.blogger.com/atom/ns#' term='dnotify'/><category scheme='http://www.blogger.com/atom/ns#' term='kernel'/><title type='text'>inotify Usage</title><content type='html'>wikipedia:&lt;span style="font-weight: bold;"&gt; inotify&lt;/span&gt; is a Linux Kernel subsystem that provides file system event notification. It was written by John McCutchan with help from Robert Love and later Amy Griffis to replace dnotify. It was included in the mainline kernel from release 2.6.13 (2005-06-18).&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Kernel configuration:&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;File Systems ---&gt;  [*] Inotify file change notification support &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
inotify parameters:&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;$ ls /proc/sys/fs/inotify/&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;max_queued_events  max_user_instances  max_user_watches&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
To install inotify-tools under Debian:&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;# apt-get install inotify-tools&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;/span&gt;Simple usage of inotifywait:&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;$ ls -F&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;
helo  helo_d/&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;$ inotifywait helo&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;Setting up watches.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;Watches established.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;helo OPEN&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;$ inotifywait -m -r helo_d&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;Setting up watches.  Beware: since -r was given, this may take a while!&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;Watches established.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;helo_d/ CREATE hi&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;helo_d/ OPEN hi&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;helo_d/ ATTRIB hi&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;helo_d/ CLOSE_WRITE,CLOSE hi&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;helo_d/ CREATE,ISDIR dir&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;helo_d/ OPEN,ISDIR dir&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;helo_d/ CLOSE_NOWRITE,CLOSE,ISDIR dir&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;helo_d/dir/ CREATE test&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;helo_d/dir/ OPEN test&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;helo_d/dir/ ATTRIB test&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;helo_d/dir/ CLOSE_WRITE,CLOSE test&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;helo_d/dir/ DELETE test&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:100%;"&gt;Simple usage of&lt;/span&gt; inotifywatch:&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;$ inotifywatch -r helo_d&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;Establishing watches...&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;Finished establishing watches, now collecting statistics.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;total  modify  attrib  close_write  close_nowrite  open  moved_from  moved_to  create  delete  filename&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;119    4       3       5            45             50    1           1         5       5       helo_d/dir/&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;99     0       2       2            46             48    0           0         0       1       helo_d/&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;Events:&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;IN_ACCESS: File was accessed (read) (*)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size:85%;"&gt;IN_ATTRIB: Metadata changed (permissions, timestamps, extended attributes, etc.) (*)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size:85%;"&gt;IN_CLOSE_WRITE: File opened for writing was closed (*)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size:85%;"&gt;IN_CLOSE_NOWRITE: File not opened for writing was closed (*)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size:85%;"&gt;IN_CREATE: File/directory created in watched directory (*)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size:85%;"&gt;IN_DELETE: File/directory deleted from watched directory (*)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size:85%;"&gt;IN_DELETE_SELF: Watched file/directory was itself deleted&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size:85%;"&gt;IN_MODIFY: File was modified (*)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size:85%;"&gt;IN_MOVE_SELF: Watched file/directory was itself moved&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size:85%;"&gt;IN_MOVED_FROM: File moved out of watched directory (*)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size:85%;"&gt;IN_MOVED_TO: File moved into watched directory (*)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size:85%;"&gt;IN_OPEN: File was opened (*)&lt;br /&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;When  monitoring a directory, the events marked with an asterisk (*) above can occur for files in the directory, in which case the name field in the returned inotify_event structure identifies the name of the file within the directory.&lt;br /&gt;
&lt;br /&gt;
API:&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;int inotify_init(void);&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;int inotify_add_watch(int fd, const char *pathname, uint32_t mask);&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;int inotify_rm_watch(int fd, uint32_t wd);&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;&lt;br /&gt;
&lt;/span&gt;Example C code&lt;span style="font-size:85%;"&gt;:&lt;/span&gt;&lt;span style="font-family:monospace;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;pre&gt;#include &lt;stdio.h&gt;
#include &lt;errno.h&gt;
#include &lt;inotifytools h=""&gt;

int main(void)
{
int fd, wd, sz;
struct inotify_event buf;

if ((fd = inotify_init()) &lt; wd =" inotify_add_watch(fd," sz =" sizeof(struct"&gt;&lt;/inotifytools&gt;&lt;/errno.h&gt;&lt;/stdio.h&gt;&lt;/pre&gt;&lt;br /&gt;
Reference:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://inotify-tools.sourceforge.net/"&gt;inotify-tools&lt;/a&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Inotify"&gt;wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.kernel.org/pub/linux/kernel/people/rml/inotify/"&gt;linux kernel inotify&lt;/a&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1626185782516232162-7410080265696831621?l=winfred-lu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://winfred-lu.blogspot.com/feeds/7410080265696831621/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1626185782516232162&amp;postID=7410080265696831621' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/7410080265696831621'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/7410080265696831621'/><link rel='alternate' type='text/html' href='http://winfred-lu.blogspot.com/2008/07/inotify.html' title='inotify Usage'/><author><name>Winfred</name><uri>http://www.blogger.com/profile/15649970719010644298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm2.static.flickr.com/1104/569054989_83809a02b2_m.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1626185782516232162.post-7255129819520825618</id><published>2007-05-29T17:26:00.000-07:00</published><updated>2010-03-31T20:10:34.363-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firefox'/><category scheme='http://www.blogger.com/atom/ns#' term='greasemonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='wiki'/><category scheme='http://www.blogger.com/atom/ns#' term='wikimedia'/><title type='text'>Wikimedia as a presentation application</title><content type='html'>I tried wikimedia &lt;a href="http://meta.wikimedia.org/wiki/Slides_extension"&gt;slides extension&lt;/a&gt; at first. It worked fine. However, if you'd like to present on wikimedia, I recommend another interesting approach: one of the &lt;a onclick="javascript:urchinTracker ('/outgoing/userscripts.org/tag/wikipedia');" href="http://userscripts.org/tag/wikipedia"&gt;Firefox Greasemonkey scripts&lt;/a&gt; - &lt;a href="http://userscripts.org/scripts/show/6372"&gt;&lt;span style="font-size:130%;"&gt;Wikipedia Presentation&lt;/span&gt;&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
This script automatically enables viewing any mediawiki page as a slideware presentation without modifying the page itself. Trust me, it is worth giving it a try!&lt;br /&gt;
&lt;br /&gt;
Reference: &lt;a href="http://www.darcynorman.net/2007/05/02/mediawiki-as-a-presentation-application"&gt;mediawiki as a presentation application&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;center&gt;&lt;br /&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_abhx4EO9uhw/RlzP0nwxvbI/AAAAAAAAADA/daWNCEM98oc/s1600-h/2007-05-30_090445.png"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_abhx4EO9uhw/RlzP0nwxvbI/AAAAAAAAADA/daWNCEM98oc/s320/2007-05-30_090445.png" alt="" id="BLOGGER_PHOTO_ID_5070155783446052274" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_abhx4EO9uhw/RlzQCXwxvcI/AAAAAAAAADI/Lu9ULvjDDjU/s1600-h/2007-05-30_090738.png"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_abhx4EO9uhw/RlzQCXwxvcI/AAAAAAAAADI/Lu9ULvjDDjU/s320/2007-05-30_090738.png" alt="" id="BLOGGER_PHOTO_ID_5070156019669253570" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1626185782516232162-7255129819520825618?l=winfred-lu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://winfred-lu.blogspot.com/feeds/7255129819520825618/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1626185782516232162&amp;postID=7255129819520825618' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/7255129819520825618'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/7255129819520825618'/><link rel='alternate' type='text/html' href='http://winfred-lu.blogspot.com/2007/05/wikimedia-as-presentation-application.html' title='Wikimedia as a presentation application'/><author><name>Winfred</name><uri>http://www.blogger.com/profile/15649970719010644298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm2.static.flickr.com/1104/569054989_83809a02b2_m.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_abhx4EO9uhw/RlzP0nwxvbI/AAAAAAAAADA/daWNCEM98oc/s72-c/2007-05-30_090445.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1626185782516232162.post-5857467845531842873</id><published>2007-05-10T01:15:00.000-07:00</published><updated>2011-04-20T19:25:17.998-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mantis'/><category scheme='http://www.blogger.com/atom/ns#' term='cvs'/><category scheme='http://www.blogger.com/atom/ns#' term='viewcvs'/><category scheme='http://www.blogger.com/atom/ns#' term='viewvc'/><title type='text'>Add Mantis links to ViewVC (ViewCVS)</title><content type='html'>A small modification to ViewVC adding links to our mantis system:&lt;br /&gt;
&lt;pre&gt;&lt;span class="Type"&gt;--- lib/viewvc.py.orig  2007-05-10 10:39:10.000000000 +0800&lt;/span&gt;
&lt;span class="Type"&gt;+++ lib/viewvc.py       2007-05-10 11:17:00.000000000 +0800&lt;/span&gt;
&lt;span class="Statement"&gt;@@ -973,10 +973,12 @@&lt;/span&gt;
 # addresses.  Note that the regexps assume the text is already HTML-encoded.
 _re_rewrite_url = re.compile('((http|https|ftp|file|svn|svn\+ssh)(://[-a-zA-Z0-9%.~:_/]+)((\?|\&amp;amp;amp;)([-a-zA-Z0-9%.~:_]+)=([-a-zA-Z0-9%.~:_])+)*(#([-a-zA-Z0-9%.~:_]+)?)?)')
 _re_rewrite_email = re.compile('([-a-zA-Z0-9_.\+]+)@(([-a-zA-Z0-9]+\.)+[A-Za-z]{2,4})')
&lt;span class="Identifier"&gt;+_re_rewrite_mantis = re.compile('(issue)([\ \#]+)(\d{1,7})')&lt;/span&gt;
 def htmlify(html):
   html = cgi.escape(html)
   html = re.sub(_re_rewrite_url, r'&amp;lt;a href=&amp;quot;\1&amp;quot;&amp;gt;\1&amp;lt;/a&amp;gt;', html)
   html = re.sub(_re_rewrite_email, r'&amp;lt;a href=&amp;quot;mailto:\1&amp;amp;#64;\2&amp;quot;&amp;gt;\1&amp;amp;#64;\2&amp;lt;/a&amp;gt;', html)
&lt;span class="Identifier"&gt;+  html = re.sub(_re_rewrite_mantis, r'&amp;lt;a href=&amp;quot;/mantis/view.php?id=\3&amp;quot;&amp;gt;\1\2\3&amp;lt;/a&amp;gt;', html)&lt;/span&gt;
   return html

 def format_log(log, cfg):
&lt;span class="Statement"&gt;@@ -1310,6 +1312,7 @@&lt;/span&gt;
   html = pp.fontify(html)
   html = re.sub(_re_rewrite_url, r'&amp;lt;a href=&amp;quot;\1&amp;quot;&amp;gt;\1&amp;lt;/a&amp;gt;', html)
   html = re.sub(_re_rewrite_email, r'&amp;lt;a href=&amp;quot;mailto:\1&amp;quot;&amp;gt;\1&amp;lt;/a&amp;gt;', html)
&lt;span class="Identifier"&gt;+  html = re.sub(_re_rewrite_mantis, r'&amp;lt;a href=&amp;quot;/mantis/view.php?id=\3&amp;quot;&amp;gt;\1\2\3&amp;lt;/a&amp;gt;', html)&lt;/span&gt;
   return html

 def markup_stream_php(fp, cfg):&lt;/pre&gt;&lt;br /&gt;
I believe it would be quite easy to understand the modification, which substitutes 'issue #id' to an URL link to mantis system.&lt;br /&gt;
&lt;br /&gt;
For automatically adding a note to mantis when commit to CVS, please reference &lt;a href="http://www.mantisbt.org/manual/manual.installation.cvs.integration.php"&gt;CVS Integration&lt;/a&gt; in &lt;a href="http://www.mantisbt.org/manual/"&gt;Mantis manual&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1626185782516232162-5857467845531842873?l=winfred-lu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://winfred-lu.blogspot.com/feeds/5857467845531842873/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1626185782516232162&amp;postID=5857467845531842873' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/5857467845531842873'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/5857467845531842873'/><link rel='alternate' type='text/html' href='http://winfred-lu.blogspot.com/2007/05/add-mantis-links-to-viewvc-viewcvs.html' title='Add Mantis links to ViewVC (ViewCVS)'/><author><name>Winfred</name><uri>http://www.blogger.com/profile/15649970719010644298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm2.static.flickr.com/1104/569054989_83809a02b2_m.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1626185782516232162.post-6894832933843583561</id><published>2007-03-28T19:28:00.000-07:00</published><updated>2010-03-31T20:11:47.953-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='freebsd'/><category scheme='http://www.blogger.com/atom/ns#' term='vmware'/><category scheme='http://www.blogger.com/atom/ns#' term='virtual pc'/><title type='text'>Running FreeBSD over MS Windows</title><content type='html'>Running FreeBSD on Microsoft Virtual PC 2007 step by step:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;download and install &lt;a href="http://www.microsoft.com/windows/products/winfamily/virtualpc/default.mspx"&gt;Microsoft Virtual PC 2007&lt;/a&gt;&lt;br /&gt;
&lt;/li&gt;

&lt;li&gt;download the &lt;a href="http://www.vmware.com/vmtn/appliances/directory/717"&gt;FreeBSD vmdk file&lt;/a&gt; from &lt;a href="http://www.vmware.com/"&gt;VMware&lt;/a&gt;'s &lt;a href="http://www.vmware.com/vmtn/appliances/directory/cat/45"&gt;Virtual Appliance Marketplace - OS&lt;/a&gt; &lt;a href="http://www.vmware.com/vmtn/appliances/directory/717"&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/li&gt;

&lt;li&gt;download and install &lt;a href="http://vmtoolkit.com/files/folders/converters/entry8.aspx"&gt;VMDK to VHD converter &lt;/a&gt;(You may need &lt;a href="http://msdn2.microsoft.com/en-us/netframework/default.aspx"&gt;.NET Framework&lt;/a&gt; to run it.)&lt;/li&gt;

&lt;/ol&gt;&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;ol start="4"&gt;&lt;li&gt;convert vmdk files to a vhd file&lt;br /&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_abhx4EO9uhw/RgtVO6z26yI/AAAAAAAAABw/unE4nGO2hHA/s1600-h/vmdk2vhd.png"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_abhx4EO9uhw/RgtVO6z26yI/AAAAAAAAABw/unE4nGO2hHA/s320/vmdk2vhd.png" alt="" id="BLOGGER_PHOTO_ID_5047221522192067362" border="0" /&gt;&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;Create a FreeBSD virtual machine on Microsoft Virtual PC&lt;br /&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_abhx4EO9uhw/Rgtciqz26zI/AAAAAAAAAB4/tdogJhmPc_c/s1600-h/vm1.png"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_abhx4EO9uhw/Rgtciqz26zI/AAAAAAAAAB4/tdogJhmPc_c/s320/vm1.png" alt="" id="BLOGGER_PHOTO_ID_5047229558075878194" border="0" /&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_abhx4EO9uhw/RgtePqz260I/AAAAAAAAACA/GSQwECkS2nw/s1600-h/vm2.png"&gt;&lt;br /&gt;
&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_abhx4EO9uhw/RgtePqz260I/AAAAAAAAACA/GSQwECkS2nw/s320/vm2.png" alt="" id="BLOGGER_PHOTO_ID_5047231430681619266" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_abhx4EO9uhw/Rgteoqz261I/AAAAAAAAACI/YH5cm7TX3c0/s1600-h/vm4.png"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_abhx4EO9uhw/Rgteoqz261I/AAAAAAAAACI/YH5cm7TX3c0/s320/vm4.png" alt="" id="BLOGGER_PHOTO_ID_5047231860178348882" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_abhx4EO9uhw/Rgte36z262I/AAAAAAAAACQ/92Pyb4F7YhU/s1600-h/vm6.png"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_abhx4EO9uhw/Rgte36z262I/AAAAAAAAACQ/92Pyb4F7YhU/s320/vm6.png" alt="" id="BLOGGER_PHOTO_ID_5047232122171353954" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_abhx4EO9uhw/RgtfTKz263I/AAAAAAAAACY/rTYrpjrjTgA/s1600-h/vm7.png"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_abhx4EO9uhw/RgtfTKz263I/AAAAAAAAACY/rTYrpjrjTgA/s320/vm7.png" alt="" id="BLOGGER_PHOTO_ID_5047232590322789234" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/li&gt;

&lt;li&gt;Start FreeBSD and enjoy it!&lt;br /&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_abhx4EO9uhw/Rgtge6z265I/AAAAAAAAACo/LRrjU8C5jmo/s1600-h/vm9.png"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_abhx4EO9uhw/Rgtge6z265I/AAAAAAAAACo/LRrjU8C5jmo/s320/vm9.png" alt="" id="BLOGGER_PHOTO_ID_5047233891697879954" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_abhx4EO9uhw/Rgtgs6z266I/AAAAAAAAACw/DBixFTLA8c4/s1600-h/vm10.png"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_abhx4EO9uhw/Rgtgs6z266I/AAAAAAAAACw/DBixFTLA8c4/s320/vm10.png" alt="" id="BLOGGER_PHOTO_ID_5047234132216048546" border="0" /&gt;&lt;br /&gt;
&lt;/a&gt;&lt;br /&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_abhx4EO9uhw/RgtgyKz267I/AAAAAAAAAC4/ybbg9WidBVo/s1600-h/vm12.png"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_abhx4EO9uhw/RgtgyKz267I/AAAAAAAAAC4/ybbg9WidBVo/s320/vm12.png" alt="" id="BLOGGER_PHOTO_ID_5047234222410361778" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1626185782516232162-6894832933843583561?l=winfred-lu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://winfred-lu.blogspot.com/feeds/6894832933843583561/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1626185782516232162&amp;postID=6894832933843583561' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/6894832933843583561'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/6894832933843583561'/><link rel='alternate' type='text/html' href='http://winfred-lu.blogspot.com/2007/03/running-freebsd-on-microsoft-virtual-pc.html' title='Running FreeBSD over MS Windows'/><author><name>Winfred</name><uri>http://www.blogger.com/profile/15649970719010644298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm2.static.flickr.com/1104/569054989_83809a02b2_m.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_abhx4EO9uhw/RgtVO6z26yI/AAAAAAAAABw/unE4nGO2hHA/s72-c/vmdk2vhd.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1626185782516232162.post-4174035600947257026</id><published>2007-03-22T21:59:00.000-07:00</published><updated>2007-03-28T19:43:58.767-07:00</updated><title type='text'>緣起</title><content type='html'>看到&lt;a href="http://gen2linux.blogspot.com/"&gt;gen2linux&lt;/a&gt;在的blogger上的文章，想到好久之前也曾在這註冊了winfred，但忘了是用哪一個email註冊的… 唉，看來這個&lt;a href="http://winfred.blogspot.com/"&gt;winfred.blogspot.com&lt;/a&gt;是要不回來了 &gt;_&lt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1626185782516232162-4174035600947257026?l=winfred-lu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://winfred-lu.blogspot.com/feeds/4174035600947257026/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1626185782516232162&amp;postID=4174035600947257026' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/4174035600947257026'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1626185782516232162/posts/default/4174035600947257026'/><link rel='alternate' type='text/html' href='http://winfred-lu.blogspot.com/2007/03/gen2linux-bloggerwinfredemail-winfred.html' title='緣起'/><author><name>Winfred</name><uri>http://www.blogger.com/profile/15649970719010644298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm2.static.flickr.com/1104/569054989_83809a02b2_m.jpg'/></author><thr:total>0</thr:total></entry></feed>
