Β A very simple Assembly code to print items in a list. Hopefully the comments will explain it better. π
#FILE: print_it.s
#PURPOSE: This program copies the value in data_items to %eax and prints it off one by one in a loop.
#VARIABLES: The registers have the following uses:
#
# %edi – Holds the index of the data item being examined
# %eax – Current data item
#
# The following memory locations are used:
#
# data_items – contains the item data. A 0 is used
# to terminate the data
#data section. holds all important variables.
.section .data
data_items:
.long 67,3,34,-255,45,75,54,34,44,33,22,11,66,0 #values ending with a ‘0’.
printer:
.ascii “Current value of EAX is %d \n” # this format string which expands later on. Think about printf’s in C.
#text section. this is the actual code itself.
.section .text
.globl _start
_start: #every executable piece of code has _start
movl $0, %edi # move 0 into the index register (i.e., we want position 0)
movl data_items(, %edi, 4), %eax # data_items + index_register_edi_position * 4.
# (value of index_register_edi_position increments from 0 towards inifinty, see below inside start_loop)
# This is a mode of addressing memory. “4” is needed
# because it means 4-byte wide (my machine is 32-bit x86)
# and this value must be a multiple of 1,2,4,8,16 …otherwise memory mis-alignment issues will occur.
pushl %eax #push %eax into the stack
pushl $printer #push $printer (our format-string) into the stack
call printf #call printf function (this is dynamically linked to C library at run-time)
start_loop: # think of GOTO like syntax. π easy heh?
cmpl $0, %eax #compare 0 with the value in %eax. to check if we hit the end of the tunnel.
je loop_exit #if they are equal, jump to loop_exit [think GOTO again]
incl %edi #increment %edi counter #or else, increment %edi by 1
movl data_items(, %edi, 4), %eax #see above.
pushl %eax #see above
pushl $printer #see above
call printf #print the format-string, see above
popl %eax #pop the contents off the stack
popl %eax #pop the contents off the stack
jmp start_loop #this is the way loops are implemented in Assembly.
loop_exit:
movl $1, %eax; #the value 1 in Linux Systems Programmer’s Manual refers to the exit system call.
# system calls are a way for programmers to call kernel and request service from it.
# In this particular instance, we need to halt the program using exit.
int $0x80; # break out and let kernel do what it does.
Assemble –
$ as print_it.s -o print_it.o
Link –
$ ld print_it.o -o print_it -lc -dynamic-linker /lib/ld-linux.so.2
Execute –
$ ./print_it </blockquote>
Put all nicely in a Makefile –
all:
as print_it.s -o print_it.o;
ld print_it.o -o print_it -lc -dynamic-linker /lib/ld-linux.so.2;
run:
./print_it;
Run the Makefile –
$ make;
Run the code –
$ make run
Note: the “-lc” means to use C library (libc.so on Gnu/Linux systems) so that we can use
printf and exit function call in our code.
The option “-dynamic-linker /lib/ld-linux.so.2” allows the program to be linked to libraries.
This builds the executable so that before executing, the OS will load the
program /lib/ld-linux.so.2 to load in external libraries and link them with
the program.
Enjoy the facade of ASM. π [BTW, FYI, the executable binary is ~2k]