Assembly
Scott Lanning
slanning at buphy.bu.edu
Sat Jan 29 10:49:05 EST 2000
On Sat, 29 Jan 2000, Anthony J. Gabrielson wrote:
> I have two questions. First can anybody tell me about the Linux
>assembler, I think its called gas - but not sure. Second does anyone know
>where I can find all the interrupt functions listed? I am getting into
>assembley and need a few pointers so as always any help is appreciated.
Read the assembly howto. The author has a webpage
http://lightning.voshod.com/asm/
which is very good on Linux assembly w/o using C library calls
(i.e., using system calls). So it's similar to DOS "int 21h"
in that you set 'eax' and other registers, then "int 80h"
which will call the corresponding system call. On that webpage
is given a nice list of system calls and their corresponding
numbers (which you put in eax). The advantage of using
system calls directly rather than calling C lib functions
is you reduce alot of overhead (which the guy on that webpage
demonstrates), but on the other hand you have to implement
the functions yourself. As an example, I created a version of
the 'cat' utitility which is 444 bytes long vs. 10492 bytes
of the one with Red Hat 6.1 (it only does one file specified
on the command line, though, not accept stdin or multiple files).
The effect is rather dramatic, I think , and besides it's fun
to play with. At the moment, time permitting, I am trying to
be able to use sys_socketcall to connect to another host, but
haven't had much success so far.
I suggest one method to learn how some assembly in gas works
is to use to make test C programs, say foo.c, then compile with
as -S foo.c
then examine the resulting foo.s file. For an example, I provide
here my cat.s file; I only just started a while ago, so it's
probably pretty primitive:
-------------------------
BUF_LEN = 8192
O_RDONLY = 0
.lcomm buf, BUF_LEN #buffer for reading
.text
.globl _start #entry point declared for linker (ld)
_start:
pop %ecx #pop argument count
dec %ecx #is there anything on command line?
jz exit #no, exit
pop %ecx #skip name of program
movl $5, %eax #sys_open
pop %ebx #filename
movl $O_RDONLY, %ecx #mode
int $0x80 #call sys_open
movl %eax, %ebp #fd returned from open()
test %eax,%eax #have we opened file?
jns .read #yes, read it
jmp exit #no, exit
.read:
movl $buf, %ecx #buffer
.loop:
movl $3, %eax #sys_read
movl %ebp, %ebx #fd
movl $BUF_LEN, %edx #buffer length
int $0x80 #call sys_read
test %eax, %eax #is zero?
jz exit #yes, exit
movl %eax, %edx
movl $4, %eax #sys_write
movl $1, %ebx #fd == 1 == stdout
int $0x80
jmp .loop
exit:
movl $1, %eax
movl $0, %ebx
int $0x80
-----------------------------------
Also, it is useful to have some macros, which you use
the .include command for, like
.include "macros.s"
then in macros.s, have some things like the following
------------------------
# WRITE OUTPUT TO STDOUT
#(modifies registers eca,edb)
#you must set ecx and edx before calling this function
#ecx = pointer to buffer to output
#edx = how many bytes to output
.macro PRINT
movl $4, %eax # number of system call == 4
movl $1, %ebx # file descriptor == 1 (stdout)
int $0x80
.endm
# EXIT
.macro EXIT status
movl $1, %eax
movl $\status, %ebx
int $0x80
.endm
here:
.ascii "here\n\0"
STRLEN = . - here
# DEBUG
.macro DEBUG
pushl %eax
pushl %ebx
pushl %ecx
pushl %edx
movl $here, %ecx
movl $STRLEN, %edx
PRINT
popl %edx
popl %ecx
popl %ebx
popl %eax
.endm
---------------------------
and call them like
EXIT 0
would exit your program with a sucessful status.
-
Subcription/unsubscription/info requests: send e-mail with
"subscribe", "unsubscribe", or "info" on the first line of the
message body to discuss-request at blu.org (Subject line is ignored).
More information about the Discuss
mailing list