Sei sulla pagina 1di 7

ASSEMBLY LANGUAGE CRASH COURSE

CSC231 2-Hour Crash Course


--D. Thiebaut 15:00, 4 March 2011 (EST)

http://cs.smith.edu/dftwiki/index.php/CSC231_2-Hour_Crash_Course

This lab assumes that you have the open-source nasm assembler available and that you are working
under Linux or Mac OS X. The one-evening assembly crash course is meant to present assembly
language concepts on the Pentium as a preparation for writing assembly language programs in
Hexadecimal for the 6801 HeathKit.

Note: Information about how to make nasm, ld, and gcc work together is provided in the Sys-Admin
section at the end...

Contents
[hide]

1 The architecture of the


Pentium
2 Login

3 Simple I/O in assembly

3.1 Exercise #1:

4 Basic instructions and


operands

4.1 Exercise #2

4.2 Exercise #3

5 Addressing Modes

5.1 Exercise #4

6 Loops

6.1 Exercise #5

7 Tests

7.1 Exercise #6

8 Functions

8.1 Exercise #7

9 Solutions

10 Information for the SysAdmin

10.1 On Ubuntu

10.2 On Fedora

The architecture of the Pentium


Registers

EAX, EBX, ECX, EDX

ESI, EDI

EIP

ESP, EBP

Login

Login to Hadoop0

Simple I/O in assembly

Get a copy of the following programs. If you are using 270b-xx class accounts, try using
the getcopy command to copy them directly into your working directory.

driver.c

asm_io.asm

asm_io.inc

prog1.asm

Example of how you would get the files to your 270b-xx account:

getcopy driver.c getcopy asm_io.asm getcopy asm_io.inc getcopy prog1.asm

Exercise #1:
Assemble, link and run the program.

nasm -f elf asm_io.asm # (do this only once for all the exercises) nasm -f elf prog1.asm
gcc -o prog1 -m32 driver.c prog1.o asm_io.o ./prog1

Basic instructions and operands

mov dest, src

add dest, src

prog2.asm

section .data a dd 3 b dd 5 result dd 0


section .text global asm_main
asm_main: mov eax,[a] add eax,[b] mov [result],eax mov eax,[result] ; pass
result to print_int call print_int ; and print value ret

Exercise #2
Create and run the program. Verify that it outputs the sum of the two variables

Exercise #3

Modify the program so that it computes the sum of 5 variables containing the numbers 3, 5, 8, 10, and 20.
Your program should output this sum.

Addressing Modes
we can access memory using the address of a variable plus an offset:

a dd 3 b dd 5 ... ; sum up two variables in eax mov eax, [a] add eax, [b]
can also be written as mov eax, [a] add eax, [a+4]

When dealing with an array of several values, it's easier to use an index, either ESI, or EDI.

table dd 3, 5, 8, 10, 20 result dd 0 mov esi,table ; esi gets address of


table variable mov eax,[esi] ; get first dword of table in eax add esi, 4 ;
make esi point to next dword add eax, [esi] ; add second dword of table to
eax add esi, 4 ; make esi point to third dword add eax, [esi] ; add third
dword to eax add esi, 4 ; esi points to 4th dword add eax, [esi] ; add 4th
dword to eax add esi, 4 ; esi points to last dword add eax, [esi] ; add last
dword to sum mov [result],eax ; save sum in variable result

If needed, we can use and offset along with the index. Here's another way of summing up two variables:

a dd 3 b dd 5 result dd 0 ... mov esi, a ; make esi point to a mov eax, [esi]
; get 1st variable add eax, [esi+?] ; figure out what number to use! mov
[esi+?],eax ; store result. Figure out the offset!

Exercise #4
Write the program that will store the first five fibonacci numbers in the array table defined as:

table dd 1, 1, 0, 0, 0

The final content of the table should be 1, 1, 2, 3, 5. Your program should use the recurrence equation:

Fibn = Fibn-1 + Fibn-2.

Loops

Loops can easily be implemented: store the number of times you need to repeat a block of code in ecx, and
prefix the first instruction of the block with a label, as follows:

mov ecx, 5 ; get ready to loop 5 times mov eax, 1 ; start with 1 in eax
repeat: call print_int ; print eax to the screen add eax, 2 ; add 2 to eax
loop repeat ; repeat 5 times

Exercise #5
Rewrite the program that sums up the 5 numbers in the array table using a loop.

Tests
Tests can be used to compare quantities and to perform a two-way branch depending on the result.

cmp eax, 3
msg1

; compare eax to 3 jne there

; if they are not equal, go to "there" mov eax,

; otherwise print msg1 call print_string jmp done

there: mov eax, msg2


done: ...

; skip over next 2 instructions

; print msg2 call print_string

; end up here in both cases

If eax contains a value different from 3, the code above prints whatever string is at address msg2,
otherwise, if eax is 3, the code prints the contents of msg1.

Exercise #6
Assume that you have an array of 10 numbers, write the code that will print only the numbers that are
different from 0.

table dd 0, 1, 0, 10, 11, 4, 0, 0, 100, 0

Functions

Functions work in a way similar to the functions used in higher level language, except that there isn't a
natural way to pass parameters. Parameters are typically passed in registers (by preloading the eax, ebx,
ecx, or edx registers before the call), or by pushing them in the stack before calling the function. For today,
we'll look only at passing parameters via registers. Let's write a program that uses a function to which we
pass two integers, say 3, and 5, and the function outputs:
the sum of 3 and 5 is 8
If we pass it two new values, say 10, and 20, it will output
the sum of 10 and 20 is 30

section .text global asm_main


;;;
----------------------------------------------------------- ;;; sumfunc: ebx
and ecx are assumed to contain 2 integers that ;;; this function will add
together, and display
;;; a string of the form "the sum of x and y is z"
;;; msg1, msg2, and msg3 are 3 strings declared in the ;;; data segments
;;; ----------------------------------------------------------- sumfunc: mov
eax, msg1 ; "the sum of " call print_string mov eax, ebx ; print int in ebx
call print_int
mov eax, msg2 ; " and " call print_string mov eax, ecx ;
print int in ecx call print_int mov eax, msg3 ; " is " call
print_string ... ; figure out what 3 instructions ... ; are necessary to
print ebx plus ... ; ecx call print_nl ; print new-line character ret
asm_main: mov ebx, 3 mov ecx, 5 call sumfunc ; prints "the sum of 3 and 5 is
8" mov ebx, 10 mov ecx, 20 call sumfunc ; prints "the sum of 10 and 20 is
30"

Exercise #7
Assume that we have two arrays of integers, A, and B. A has 5 integers. B has 10 integers. Write a function
to which we can pass an array and the number of integers it contains, and the function displays only the
numbers of the array that are not zero.

A dd 1, 0, 2, 0, 5 B dd 1, 0, 0, 3, 1, 2, 0, 0, 9, 7

Solutions
prog1.asm prog2.asm prog3.asm prog4.asm prog5.asm prog6.asm prog7.asm

Information for the Sys-Admin

To make nasm, ld, and gcc work together, we have to stay in 32-bit mode, even though the

architecture is 64 bit long.

nasm should be a recent version

gcc will be in 64-bit mode, and libgcc-devel.i386 should be installed to allow gcc to compile and link
32-bit object files

On Ubuntu

Login to Hadoop0

install libgcc-devel

sudo apt-get install libc6-dev-i386

test sample program (prog1.asm) above:

nasm -f elf prog1.asm nasm -f elf asm_io.asm gcc -m32 driver.c *.o ./a.out

It should work!

On Fedora

Haven't solved that yet...

Potrebbero piacerti anche