CSC231 2-Hour Crash Course

From dftwiki3
Revision as of 15:02, 4 March 2011 by Thiebaut (talk | contribs) (Simple I/O in assembly)
Jump to: navigation, search

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


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


The architecture of the Pentium

  • Registers
    • EAX, EBX, ECX, EDX
    • ESI, EDI
    • EIP
    • ESP, EBP

Simple I/O in assembly

Get a copy of the following programs:

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 driver.c prog1.o asm_io.o
 ./prog1
   

Basic instructions and operands

       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


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           ; 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, 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