摘要:The following is designed to be a Linux equivalent to
Developing Assembly Language Programs on a PC
by Douglas V
Hall
This tutorial requires the following:
Introduction
The following is designed to be a Linux equivalent to
Developing Assembly Language Programs on a PC
by Douglas V
Hall
This tutorial requires the following:
an i
family PC running Linux
as
the GNU assembler (included with any gcc installation) ld
the GNU linker (also included with gcc) gdb
the GNU debugger The tutorial was developed on a
Redhat Linux installation running a
version kernel and the version
and
C language libraries with ELF file format
But I have tried to make the tutorial as general possible with respect to Linux systems
I highly recommend working through this tutorial with
as
and
gdb
documentation close at hand
Overview
The process of developing an assembly program under linux is somewhat different from development under NT
In order to accommodate object oriented languages which require the compiler to create constructor and destructor methods which execute before and after the execution of
main
the GNU development model embeds user code within a wrapper of system code
In other words
the user
s
main
is treated as a function call
An advantage of this is that user is not required to initialize segment registers
though user code must obey some function requirements
The Code
The following is the Linux version of the average temperature program
It will be referred to as
average
s
Note: Assembly language programs should use the
s
suffix
/* linux version of AVTEMP
ASM CS
fall
*/
data /* beginning of data segment */
/* hi_temp data item */
type hi_temp
@object /* declare as data object */
size hi_temp
/* declare size in bytes */
hi_temp:
byte
x
/* set value */
/* lo_temp data item */
type lo_temp
@object
size lo_temp
lo_temp:
byte
x
/* av_temp data item */
type av_temp
@object
size av_temp
av_temp:
byte
/* segment registers set up by linked code */
/* beginning of text(code) segment */
text
align
/* set
double
word alignment */
globl main /* make main global for linker */
type main
@function /* declare main as a function */
main:
pushl %ebp /* function requirement */
movl %esp
%ebp /* function requirement */
movb hi_temp
%al
addb lo_temp
%al
movb $
%ah
adcb $
%ah
movb $
%bl
idivb %bl
movb %al
av_temp
leave /* function requirement */
ret /* function requirement */
assembly instructions
This code may be assembled with the following command:
as
a
gstabs
o average
o average
s
The
a
option prints a memory listing during assembly
This output gives the location variables and code with respect to the beginnings of the data and code segments
gstabs
places debugging information in the executable (used by gdb)
o
specifies average
o as the output file name (the default is a
out
which is confusing since the file is not executable
)
The object file (average
o) can then be linked to the Linux wrapper code in order to create an executable
These files are crt
o
crti
o and crtn
o
crt
o and crti
o provide initialization code and crtn
o does cleanup
These should all be located in
/usr/lib
be may be elsewere on some systems
They
and their source
might be located by executing the following find command:
find /
name
crt*
print
The link command is the following:
ld
m elf_i
static /usr/lib/crt
o /usr/lib/crti
o
lc average
o /usr/lib/crtn
o
m elf_i
instructs the linker to use the ELF file format
static
cause static rather than dynamic linking to occur
And
lc
links in the standard c libraries (libc
a)
It might be necessary to include
I/libdirectory
in the invocation for ld to find the c library
It will be necessary to change the mode of the resulting object file with
chmod +x
/a
out
It should now be possible to execute the file
But
of course
there will be no output
I recommend placing the above commands in a makefile
debugging
The
gstabs
option given to the assembler allows the assembly program to be debugged under gdb
The first step is to invoke gdb:
gdb
/a
out
gdb should start with the following message:
[bjorn@pomade src]$ gdb
/a
out
GNU gdb
Copyright
Free Software Foundation
Inc
GDB is free software
covered by the GNU General Public License
and you are
welcome to change it and/or distribute copies of it under certain conditions
Type
show copying
to see the conditions
There is absolutely no warranty for GDB
Type
show warranty
for details
This GDB was configured as
i
redhat
linux
(gdb)
The
l
command will list the program sourcecode
(gdb) l
/* linux version of AVTEMP
ASM CS
fall
*/
data /* beginning of data segment */
/* hi_temp data item */
type hi_temp
@object /* declare as data object */
size hi_temp
/* declare size in bytes */
hi_temp:
byte
x
/* set value */
/* lo_temp data item */
(gdb)
The first thing to do is set a breakpoint so it will be possible to step through the code
(gdb) break main
Breakpoint
at
x
f
(gdb)
This sets a breakpoint at the beginning of main
Now run the program
(gdb) run
Starting program: /home/bjorn/src/
/a
out
Breakpoint
main () at average
s:
movb hi_temp
%al
Current language: auto; currently asm
(gdb)
values in registers can be checked with either
info registers
(gdb) info registers
eax
x
ecx
xbffffd
edx
x
ebx
x
bf
esp
xbffffdd
xbffffdd
ebp
xbffffdd
xbffffdd
esi
x
edi
x
eip
x
f
x
f
eflags
x
cs
x
ss
x
b
ds
x
b
es
x
b
fs
x
b
gs
x
b
(gdb)
or
p/x $eax
which prints the value in the EAX register in hex
The
e
in front of the register name indicates a
bit register
The Intel x
family has included
extended
bit registers since the
These E registers are to the X registers as the L and H are to the X registers
Linux also uses a
flat
and protected memory model rather that segmentation
thus the EIP stores the entire current address
(gdb
From:http://tw.wingwit.com/Article/program/Oracle/201311/16623.html