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 o 3.1 Exercise #1: 4 Basic instructions and operands o 4.1 Exercise #2

Assembly Language Crash Course

Embed Size (px)

DESCRIPTION

Assembly Language Crash Course

Citation preview

Page 1: Assembly Language Crash Course

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

o 3.1   Exercise #1:

4   Basic instructions and

operands

o 4.1   Exercise #2

Page 3: Assembly Language Crash Course

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

Page 4: Assembly Language Crash Course

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

Page 5: Assembly Language Crash Course

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  ; compare eax to 3 jne there  ; if they are not equal, go to "there" mov eax,

msg1  ; otherwise print msg1 call print_string jmp done  ; skip over next 2 instructions

there: mov eax, msg2  ; print msg2 call print_string

done: ...  ; 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,

Page 6: Assembly Language Crash Course

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

Page 7: Assembly Language Crash Course

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...