Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Asm Linux
Asm Linux
db hola mundo,0xA
equ $ - mensaje
section .text
global _inicio
_inicio:
mov edx,longitud
mov ecx,mensaje
mov ebx,1
mov eax,4
int 0x80
mov ebx,0
mov eax,1
int 0x80
lo que nos genera el ejecutable hola que nos mostrar el mensaje definido.
db hola mundo,0xA
equ $ - mensaje
resb
resb
resw
resd
resq
rest
256
1
1
1
1
1
;REServa
;REServa
;REServa
;REServa
;REServa
;REServa
256 Bytes
1 Byte (8 bits)
1 Word (palabra, 16 bits)
1 DoubleWord (doble palabra, 32bits)
1 float de doble precision (64 bits)
1 float de precision extendida (128 bits)
....
main ENDP
codigo ends
END main
2
2
2
2
exit
read
write
open
info
info
info
info
...
exit
read
write
open
Todos esos datos quedan cargados en la pila del programa, de acuerdo a la siguiente
estructura:
argc
argv[0]
argv[1]
argv[2]
argv[3]
......
argv[argc-1]
NULL
env[1]
env[2]
env[3]
......
env[n]
NULL
Cuando el kernel carga nuestro programa, establece esa estructura en la pila del
programa. As, si nuestro programa fue llamado de la siguiente forma:
$ miprograma
37
hola
mostrar_por_pantalla:
mov edx,eax
;longitud de la cadena a escribir
mov eax,4
;funcin sys_write()
mov ebx,1
;descriptor de STDOUT
int 0x80
...
...
INTEL:
INTEL:
AT&T:
movb
movw
movl
movl
INTEL:
mov
mov
mov
mov
%bl,%al
%bx, %ax
%ebx,%eax
(%ebx),%eax
al,bl
ax, bx
eax,ebx
eax, dword ptr [ebx]
Direccionamiento a memoria:
Es uno de los aspectos que ms cambian. Veamos la sintaxis de Intel para hacer un
direccionamiento a base, con ndice y desplazamiento:
[ base + indice*escala + desplazamiento ]
INTEL:
Salto lejano
AT&T:
INTEL:
movsx ecx, ax
movzx cx, ah
cbw
cwde
cwd
cdq
GAS
section .data
[.section] .data
section .bss
[.section] .bss
section .text
[.section] .text
GAS
.text
.globl _start
_start:
GAS
.data
cero dw 0
letra db A
En la pgina web del DJGPP podemos encontrar una gua detallada sobre la sintaxis
AT&T, y ejemplos de ensamblador en lnea:
http://www.delorie.com/djgpp/doc/brennan/brennan_att_inline_djgpp.html
El programa Hola mundo con GAS.
Veamos el ejemplo que explicamos para NASM, esta vez en el formato AT&T (slo
hay que tener en cuenta las diferencias comentadas anteriormente):
.section .data
mensaje: .ascii hola mundo \n
longitud = . - mensaje
.section .text
.globl _start
_start:
movl $longitud,%edx
movl $mensaje,%ecx
movl $1,%ebx
movl $4,%eax
int $0x80
movl $0,%ebx
movl $1,%eax
int $0x80
lo que nos genera el ejecutable hola que nos mostrar el mensaje definido.
execve()
sys_execve()
sys_execve()
do_execve()
search_binary_handler()
load_elf_binary()
arch/i386/kernel/process.c
fs/exec.c
fs/exec.c
fs/binfmt_elf.c
start_thread()
include/asm-i386/processor.h
Comentarios
escribimos el nombre del programa y
pulsamos ENTER
el shell llama a la funcin
correspondiente de libc
libc pasa la llamada al kernel
la llamada llega al espacio del kernel
abre el fichero
obtiene el tipo de ejecutable
carga el binario ELF y las libreras
necesarias. Inicializa la memoria
pasa el control al cdigo del programa
de usuario
10
cdigo
datos
bss
...
...
...
pila
argumentos
vars.entorno
nombre del ejecutable
NULL
direccin 0xBFFFFFFF
La pila crece hacia direcciones de memoria menores (hacia arriba), hasta encontrarse
con la seccin .bss . Esta seccin de variables del programa es totalmente inicializada
con el valor 0 en el inicio, de forma que cualquier variable definida no contendr un
valor aleatorio al principio. Podemos evitarnos el trabajo de inicializar una variable a 0
en nuestro programa, simplemente definindola en esta seccin.
El espacio libre de memoria despus del .bss queda para asignacin dinmica de
memoria ( malloc() ).
Inicializacin de los registros
Al pasar el control a la primera instruccin de nuestro programa, el kernel (segn su
versin) habr puesto los valores de los registros generales (EAX, EBX, ECX, EDX,
ESI, EDI, EBP) a cero, o bien habr dejado los valores que tenan justo antes de que el
programa llamador hiciese la llamada:
En el kernel de versin 2.0 EAX y EDX quedan inicializados a 0, mientras que
el resto contienen los valores que tenan justo antes de la llamada a sys_execve()
En el kernel de versin 2.2 todos los registros generales quedan inicializados a 0
%ebx
int
struct pt_regs
unsigned int
unsigned int
const char *
unsigned int
pid_t
const char *
const char *
const char *
struct pt_regs
%ecx
char *
const char *
int
unsigned int *
int
const char *
-
%edx
size_t
size_t
int
int
-
%esx
-
%edi
-
11
12
13
14
15
16
sys_chdir
sys_time
sys_mknod
sys_chmod
sys_lchown
fs/open.c
kernel/time.c
fs/namei.c
fs/open.c
fs/open.c
const char *
int *
const char *
const char *
const char *
18
sys_stat
fs/stat.c
char *
19
20
21
22
23
24
25
26
27
sys_lseek
sys_getpid
sys_mount
sys_oldumount
sys_setuid
sys_getuid
sys_stime
sys_ptrace
sys_alarm
fs/read_write.c
kernel/sched.c
fs/super.c
fs/super.c
kernel/sys.c
kernel/sched.c
kernel/time.c
arch/i386/kernel/ptrace.c
kernel/sched.c
unsigned int
char *
char *
uid_t
int *
long
unsigned int
28
sys_fstat
fs/stat.c
unsigned int
29
30
33
34
36
37
38
39
40
41
42
43
45
46
47
48
49
50
51
52
sys_pause
sys_utime
sys_access
sys_nice
sys_sync
sys_kill
sys_rename
sys_mkdir
sys_rmdir
sys_dup
sys_pipe
sys_times
sys_brk
sys_setgid
sys_getgid
sys_signal
sys_geteuid
sys_getegid
sys_acct
sys_umount
arch/i386/kernel/sys_i386.c fs/open.c
char *
fs/open.c
const char *
kernel/sched.c
int
fs/buffer.c
kernel/signal.c
int
fs/namei.c
const char *
fs/namei.c
const char *
fs/namei.c
const char *
fs/fcntl.c
unsigned int
arch/i386/kernel/sys_i386.c unsigned long *
kernel/sys.c
struct tms *
mm/mmap.c
unsigned long
kernel/sys.c
gid_t
kernel/sched.c
kernel/signal.c
int
kernel/sched.c
kernel/sched.c
kernel/acct.c
const char *
fs/super.c
char *
int
mode_t
uid_t
struct __old_kernel_stat
*
off_t
char *
long
struct __old_kernel_stat
*
struct utimbuf *
int
int
const char *
int
__sighandler_t
int
dev_t
gid_t
unsigned int
char *
long
-
long
-
pid_t
unsigned
long
unsigned
long
-
54
sys_ioctl
fs/ioctl.c
unsigned int
unsigned int
55
sys_fcntl
fs/fcntl.c
unsigned int
unsigned int
57
sys_setpgid
kernel/sys.c
59
sys_olduname
60
61
62
63
64
65
66
sys_umask
sys_chroot
sys_ustat
sys_dup2
sys_getppid
sys_getpgrp
sys_setsid
pid_t
struct
arch/i386/kernel/sys_i386.c
oldold_utsname *
kernel/sys.c
int
fs/open.c
const char *
fs/super.c
dev_t
fs/fcntl.c
unsigned int
kernel/sched.c
kernel/sys.c
kernel/sys.c
-
struct ustat *
unsigned int
-
struct
old_sigaction *
old_sigset_t -
67
sys_sigaction
arch/i386/kernel/signal.c
int
const struct
old_sigaction *
68
69
70
71
72
73
74
sys_sgetmask
sys_ssetmask
sys_setreuid
sys_setregid
sys_sigsuspend
sys_sigpending
sys_sethostname
kernel/signal.c
kernel/signal.c
kernel/sys.c
kernel/sys.c
arch/i386/kernel/signal.c
kernel/signal.c
kernel/sys.c
int
uid_t
gid_t
int
old_sigset_t *
char *
uid_t
gid_t
int
int
12
75
76
77
78
79
80
81
sys_setrlimit
sys_getrlimit
sys_getrusage
sys_gettimeofday
sys_settimeofday
sys_getgroups
sys_setgroups
kernel/sys.c
kernel/sys.c
kernel/sys.c
kernel/time.c
kernel/time.c
kernel/sys.c
kernel/sys.c
82
old_select
83
sys_symlink
unsigned int
unsigned int
int
struct timeval *
struct timeval *
int
int
struct
arch/i386/kernel/sys_i386.c
sel_arg_struct *
fs/namei.c
const char *
84
sys_lstat
fs/stat.c
85
86
87
88
89
sys_readlink
sys_uselib
sys_swapon
sys_reboot
old_readdir
fs/stat.c
fs/exec.c
mm/swapfile.c
kernel/sys.c
fs/readdir.c
90
old_mmap
91
92
93
94
95
96
97
99
100
101
102
103
sys_munmap
sys_truncate
sys_ftruncate
sys_fchmod
sys_fchown
sys_getpriority
sys_setpriority
sys_statfs
sys_fstatfs
sys_ioperm
sys_socketcall
sys_syslog
const char *
const char *
const char *
int
unsigned int
struct
arch/i386/kernel/sys_i386.c mmap_arg_struct
*
mm/mmap.c
unsigned long
fs/open.c
const char *
fs/open.c
unsigned int
fs/open.c
unsigned int
fs/open.c
unsigned int
kernel/sys.c
int
kernel/sys.c
int
fs/open.c
const char *
fs/open.c
unsigned int
arch/i386/kernel/ioport.c unsigned long
net/socket.c
int
kernel/printk.c
int
104
sys_setitimer
kernel/itimer.c
105
106
107
108
sys_getitimer
sys_newstat
sys_newlstat
sys_newfstat
kernel/itimer.c
fs/stat.c
fs/stat.c
fs/stat.c
109
sys_uname
110
111
112
113
char *
struct rlimit *
struct rlimit *
struct rusage *
struct timezone *
struct timezone *
gid_t *
gid_t *
const char *
struct __old_kernel_stat
*
char *
int
int
void *
int
int
unsigned int
void *
-
size_t
unsigned long
unsigned long
mode_t
uid_t
int
int
struct statfs *
struct statfs *
unsigned long
unsigned long *
char *
struct itimerval *
struct stat *
struct stat *
struct stat *
-
sys_iopl
sys_vhangup
sys_idle
sys_vm86old
int
char *
char *
unsigned int
struct old_utsname
arch/i386/kernel/sys_i386.c
*
arch/i386/kernel/ioport.c unsigned long
fs/open.c
arch/i386/kernel/process.c arch/i386/kernel/vm86.c
unsigned long
gid_t
int
int
int
struct
itimerval *
-
struct vm86plus_struct *
114
sys_wait4
kernel/exit.c
unsigned long *
int options
115
116
117
118
119
120
121
sys_swapoff
sys_sysinfo
sys_ipc(*Note)
sys_fsync
sys_sigreturn
sys_clone
sys_setdomainname
int
int
int
-
void *
-
122
sys_newuname
mm/swapfile.c
const char *
kernel/info.c
struct sysinfo *
arch/i386/kernel/sys_i386.c uint
fs/buffer.c
unsigned int
arch/i386/kernel/signal.c unsigned long
arch/i386/kernel/process.c struct pt_regs
kernel/sys.c
char *
struct
kernel/sys.c
new_utsname *
struct
rusage *
int
-
123
sys_modify_ldt
arch/i386/kernel/ldt.c
int
void *
124
sys_adjtimex
kernel/time.c
struct timex *
125
sys_mprotect
mm/mprotect.c
unsigned long
size_t
126
sys_sigprocmask
kernel/signal.c
int
old_sigset_t *
127
sys_create_module
kernel/module.c
const char *
size_t
int
pid_t
struct itimerval *
unsigned
long
unsigned
long
old_sigset_t
*
-
13
128
129
sys_init_module
sys_delete_module
kernel/module.c
kernel/module.c
struct module *
-
fs/dquot.c
kernel/sys.c
fs/open.c
fs/buffer.c
const char *
const char *
struct kernel_sym
*
int
pid_t
unsigned int
int
130
sys_get_kernel_syms
kernel/module.c
131
132
133
134
sys_quotactl
sys_getpgid
sys_fchdir
sys_bdflush
const char *
long
caddr_t
-
sys_sysfs
fs/super.c
int
unsigned long
136
138
139
sys_personality
sys_setfsuid
sys_setfsgid
kernel/exec_domain.c
kernel/sys.c
kernel/sys.c
unsigned long
uid_t
gid_t
140
sys_llseek
fs/read_write.c
unsigned int
unsigned long
141
sys_getdents
fs/readdir.c
unsigned int
void *
int
unsigned
long
unsigned
long
unsigned int
135
142
sys_select
fs/select.c
int
fd_set *
fd_set *
143
144
sys_flock
sys_msync
fs/locks.c
mm/filemap.c
unsigned int
unsigned long
unsigned int
size_t
145
sys_readv
fs/read_write.c
unsigned long
146
sys_writev
fs/read_write.c
unsigned long
147
148
sys_getsid
sys_fdatasync
kernel/sys.c
fs/buffer.c
149
sys_sysctl
kernel/sysctl.c
150
151
152
153
154
155
sys_mlock
sys_munlock
sys_mlockall
sys_munlockall
sys_sched_setparam
sys_sched_getparam
mm/mlock.c
mm/mlock.c
mm/mlock.c
mm/mlock.c
kernel/sched.c
kernel/sched.c
pid_t
unsigned int
struct
__sysctl_args *
unsigned long
unsigned long
int
pid_t
pid_t
int
unsigned
long
unsigned
long
-
size_t
size_t
struct sched_param *
struct sched_param *
156
sys_sched_setscheduler kernel/sched.c
pid_t
int
157
158
kernel/sched.c
kernel/sched.c
pid_t
-
kernel/sched.c
162
sys_sched_getscheduler
sys_sched_yield
sys_sched_get_priority_
max
sys_sched_get_priority_
min
sys_sched_rr_get_interv
al
sys_nanosleep
163
unsigned
loff_t *
int
struct
fd_set * timeval
*
-
struct
sched_param
*
-
int
kernel/sched.c
int
kernel/sched.c
pid_t
struct timespec *
kernel/sched.c
struct timespec *
struct timespec *
mm/mremap.c
unsigned long
unsigned long
164
165
sys_setresuid
sys_getresuid
kernel/sys.c
kernel/sys.c
uid_t
uid_t *
166
sys_vm86
arch/i386/kernel/vm86.c
167
168
169
170
171
sys_query_module
sys_poll
sys_nfsservctl
sys_setresgid
sys_getresgid
kernel/module.c
fs/select.c
fs/filesystems.c
kernel/sys.c
kernel/sys.c
uid_t
uid_t *
struct vm86_struct
*
const char *
struct pollfd *
int
gid_t
gid_t *
unsigned
long
-
sys_mremap
unsigned
long
uid_t
uid_t *
172
sys_prctl
kernel/sys.c
int
173
sys_rt_sigreturn
arch/i386/kernel/signal.c
unsigned long
size_t
unsigned
long
-
size_t *
unsigned
long
-
174
sys_rt_sigaction
kernel/signal.c
int
size_t
175
sys_rt_sigprocmask
kernel/signal.c
int
size_t
159
160
161
int
unsigned int
void *
gid_t
gid_t *
char *
long
void *
gid_t
gid_t *
unsigned
unsigned long
long
struct
const struct sigaction *
sigaction *
sigset_t *
sigset_t *
14
176
sys_rt_sigpending
kernel/signal.c
sigset_t *
size_t
177
sys_rt_sigtimedwait
kernel/signal.c
const sigset_t *
siginfo_t *
178
179
180
181
182
183
184
185
186
187
190
sys_rt_sigqueueinfo
sys_rt_sigsuspend
sys_pread
sys_pwrite
sys_chown
sys_getcwd
sys_capget
sys_capset
sys_sigaltstack
sys_sendfile
sys_vfork
kernel/signal.c
arch/i386/kernel/signal.c
fs/read_write.c
fs/read_write.c
fs/open.c
fs/dcache.c
kernel/capability.c
kernel/capability.c
arch/i386/kernel/signal.c
mm/filemap.c
arch/i386/kernel/process.c
int
sigset_t *
unsigned int
unsigned int
const char *
char *
cap_user_header_t
cap_user_header_t
const stack_t *
int
struct pt_regs
int
size_t
char *
const char *
uid_t
unsigned long
cap_user_data_t
const cap_user_data_t
stack_t *
int
-
const struct
timespec *
siginfo_t *
size_t
size_t
gid_t
off_t *
-
size_t
loff_t
loff_t
size_t
-
6. Ejemplos
Uso de macros en ensamblador (GAS)
Igual que en MSDOS, podemos hacer uso de macros para facilitar la programacin.
Para ello, debemos utilizar la directiva .macro de la siguiente forma:
.macro nombreMacro
instrucciones
.endm
En el ejemplo definiremos una macro para terminar el programa, otra para mostrar una
cadena por salida estndar, y otra para leer cadenas de texto desde entrada estndar.
La forma de llamar a una macro es idntica a como se haca bajo MSDOS, incluso en la
forma de pasarle los valores:
#COMPILAR:
#
as -o m.o m.s
#
ls -o m
m.o
.macro terminar
movl $1,%eax
movl $0,%ebx
int $0x80
.endm
#espera ECX=cadena ; EDX=longitud
.macro escribir_cadena cadena longitud
movl $4,%eax
movl $1,%ebx
#stdout
movl \cadena,%ecx
movl \longitud,%edx
int $0x80
.endm
#espera ECX=cadena ; EDX=longitud
.macro leer_cadena cadena longitud
movl $3,%eax
movl $0,%ebx
#stdin
movl \cadena,%ecx
movl \longitud,%edx
int $0x80
.endm
15
.data
.text
_start:
escribir_cadena $mensaje1 $longitud1
leer_cadena
$buffer $10
escribir_cadena $retorno $1
escribir_cadena $buffer $10
escribir_cadena $retorno $1
terminar
.text
funcion_terminar:
movl $1,%eax
movl $0,%ebx
int $0x80
ret
#parmetros ECX=cadena ; EDX=longitud
funcion_escribir_cadena:
16
movl $4,%eax
movl $1,%ebx
int $0x80
ret
#stdout
movl $buffer,%ecx
movl $10,%edx
call funcion_leer_cadena
movl $retorno,%ecx
movl $1,%edx
call funcion_escribir_cadena
movl $buffer,%ecx
movl $10,%edx
call funcion_escribir_cadena
movl $retorno,%ecx
movl $1,%edx
call funcion_escribir_cadena
#esta ltima no necesita ningn parmetro
call funcion_terminar
.globl _start
_start:
pop %eax
#extraer de la pila el ARGC
repetir:
#bucle para recorrer todos los argumentos
pop %eax
#extraer el ARGV[i]
testl %eax,%eax #comprobar si es NULL
jz terminar
call funcion_pintar_cadena #llamada a la funcion
jmp repetir
terminar:
17
funcion_pintar_cadena:
#definicion de una funcion
movl %eax,%ecx
#el parametro ha sido pasado en EAX
xorl %edx,%edx
contar:
#debemos calcular la longitud del param.
movb (%ecx,%edx,$1),%al
testb %al,%al
#comprobar el caracter de la cadena
jz fin_contar
incl %edx
#vamos incrementando el calculo en EDX
jmp contar
fin_contar:
movl $4,%eax
#una vez calculada la longitud,se muestra
movl $1,%ebx
int $0x80
movl $4,%eax
movl $retorno,%ecx
movl $1,%edx
int $0x80
#mostramos el RETORNO_CARRO
#es un solo caracter
ret
Para cada parmetro llamamos a una funcin que lo muestre por salida estndar. Para
ello debe calcular la longitud de la cadena (argumento actual), contando uno por uno
cada carcter que la forma. Tras cada argumento impreso, se hace un retorno de carro
(es una cadena de caracteres de longitud 1). El programa muestra tambin el nombre del
ejecutable como primer argumento (sera casi inmediato hacer que slo muestre los
argumentos reales).
Lectura del contenido de un fichero (NASM)
El siguiente ejemplo lee los 1024 primeros bytes de un fichero que le pasemos como
primer argumento por la lnea de comandos y los muestra por salida estndar. En este
ejemplo, la sintaxis utilizada ha sido la de Intel (NASM).
;COMPILAR:
;
nasm -f elf acceso_a_fich.asm
;
ld -s -o acceso_a_fich acceso_a_fich.o
section .data
mensaje
db 0xA,"---vamos a probar esto---",0xA
longitud
equ $ - mensaje
mensaje2
db 0xA,"---hemos terminado---",0xA
longitud2
equ $ - mensaje2
tamano
section .bss
buffer:
equ 1024
resb
section .text
global _start
_start:
mov edx,longitud
mov ecx,mensaje
mov ebx,1
1024
;definimos el punto de entrada
;EDX=long. de la cadena
;ECX=cadena a imprimir
;EBX=manejador de fichero (STDOUT)
18
mov eax,4
int 0x80
pop ebx
pop ebx
;extraer "argc"
;extraer argv[0] (nombre del ejecutable)
pop
mov
mov
int
ebx
eax,5
ecx,0
0x80
test eax,eax
;comprobar si dev. error o el descriptor
jns leer_del_fichero
hubo_error:
mov ebx,eax
mov eax,1
int 0x80
leer_del_fichero:
mov ebx,eax
push ebx
mov eax,3
mov ecx,buffer
mov edx,tamano
int 0x80
js hubo_error
mostrar_por_pantalla:
mov edx,eax
mov eax,4
mov ebx,1
int 0x80
cerrar_fichero:
pop ebx
mov eax,6
int 0x80
mov
mov
mov
mov
int
mov ebx,0
mov eax,1
int 0x80
edx,longitud2
;EDX=long. de la cadena
ecx,mensaje2
;ECX=cadena a imprimir
ebx,1
;EBX=manejador de fichero (STDOUT)
eax,4
;EAX=funcin sys_write() del kernel
0x80
;interrupc. 80 (llamada al kernel)
;EBX=cdigo de salida al SO
;EAX=funcin sys_exit() del kernel
;interrupc. 80 (llamada al kernel)
Hemos hecho uso de datos constantes (seccin .data) y variables (seccin .bss) donde
guardamos los datos ledos del fichero. El acceso al fichero para abrirlo, leerlo y
cerrarlo se hace mediante las funciones del sistema (int 80h) de forma muy sencilla.
19
o prog.o
prog.s
.data:00000000 hola
.data:00000006 hola_len
.text:00000000 _start
prog.o
20
## hola.s
## COMPILAR:
## as -o hola.o hola.s
## ld -o hola
hola.o
## muestra una cadena de texto utilizando la llamada al sistema
########################################################################
.section .data
hola:
.ascii "Hola!\n"
hola_len:
.long
. - hola
########################################################################
.section .text
.globl _start
_start:
xorl %ebx, %ebx
# %ebx = 0
#
#
#
#
#
#
llamada a write()
%ebx = 0
%ebx = 1, fd = stdout
%ecx ---> hola
%edx = longitud
ejecuta write()
Antes de ejecutar el programa debemos establecer dos puntos de ruptura (break): uno
correspondiente a la etiqueta de comienzo del programa (_start) y otro en la lnea
siguiente (en el primero no para, pero es necesario ponerlo...). Vemos que al poner el
primer punto, nos indica un nmero de lnea. Nosotros debemos poner otro punto en la
lnea cuyo nmero es el siguiente al que nos acaba de indicar.
Una vez hecho esto, ya podemos ejecutar el programa (run):
(gdb) break _start
Breakpoint 1 at 0x8048074: file hola.s, line 20.
(gdb) break 21
Breakpoint 2 at 0x8048076: file hola.s, line 21.
(gdb) run
Starting program: /home/pedro/asm_linux/asm-tut/h
Breakpoint 2, _start () at hola.s:21
21
movl $4, %eax
# llamada a write()
Current language: auto; currently asm
Podemos ir viendo los valores de los registros mediante info registers o bien con p/x
$registro
21
{f
{f
{f
{f
{f
{f
{f
{f
=
=
=
=
=
=
=
=
{0,
{0,
{0,
{0,
{0,
{0,
{0,
{0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0}}
0}}
0}}
0}}
0}}
0}}
0}}
0}}
La traza paso a paso del programa la haremos con la orden step . A cada paso nos va
mostrando la instruccin a ejecutar a continuacin; mediante las rdenes anteriores
podremos ir viendo cmo cambia el contenido de los registros:
(gdb) step
22
(gdb) step
23
(gdb) step
24
(gdb) p/x $eax
$2 = 0x4
(gdb) p/x $ebx
$3 = 0x1
# %ebx = 0
incl %ebx
# %ebx = 1, fd = stdout
8. Trabajo a desarrollar
Probar los programas de ejemplo del guin (tanto los escritos para NASM como los
escritos para GAS) y comprobar el correcto funcionamiento de los mismos, corrigiendo
cualquier error que pudiera encontrarse en ellos.
Pasar los programas de la seccin 6, escritos en la sintaxis AT&T (GAS), a la sintaxis
Intel (NASM).
22
9. Enlaces interesantes
[1]
[2]
[3]
[4]
[5]
[6]
[7]
[8]
[9]
[10]
http://linuxassembly.org
http://linuxassembly.org/articles/linasm.html
http://www.leto.net/papers/writing-a-useful-program-with-nasm.txt
http://linuxassembly.org/howto/hello.html
http://linuxassembly.org/startup.html
http://linuxassembly.org/articles/startup.html
http://www.janw.easynet.be/eng.html
http://www.gnu.org/manual/gas
http://www.gnu.org/onlinedocs/gcc_toc.html
http://www.gnu.org/manual/gdb-4.17/gdb.html