background image

 

Programowanie niskopoziomowe 

Sprawozdanie 

Laboratorium 4 

 

Funkcje rekurencyjne i biblioteczne 

 

Wykonujący: 

 

Paweł Ochał 

 

Grzegorz Róg 

 

Jacek Pieprzak 

 

L04  

 

background image

 

Kod poddany asemblacji: 
 

/* plik do laboratorium 4 z architektury komputerow II */  

#include "stdio.h"  
  
/* funkcja rekurencyjna */  

unsigned int silnia(int n)  
{  
 if (n<0) return -1;  

  else if (n==0) return 1;  
   else return n * silnia(n-1);  
}  

  
//prototyp funkcji wieloargumentowej printf  
//int printf(const char * format, arg1, arg2,...);  

  
void main(void)  
{  

int i=3;  
i=silnia(i);  
printf("%d",i); /* jaka jest kolejnosc parametrow? */  

}  

Kod assemblera modelu typu Small: 

 
 

 
 
 

.386p 

 

ifndef  ??version 

?debug 

macro 

 

endm 

publicdll macro  name 
 

public  name 

 

endm 

 

endif 

 

?debug  V 300h 

 

?debug  S "..\USER\MAIN.C" 

 

?debug  C E95A908C3B0E2E2E5C555345525C4D41494E2E43 

 

?debug  C E9E8BB563B1B443A5C424F524C414E44435C494E434C5544455C53+ 

 

?debug  C 5444494F2E48 

 

?debug  C E9E9BB563B1B443A5C424F524C414E44435C494E434C5544455C5F+ 

 

?debug  C 444546532E48 

 

?debug  C E9E9BB563B1C443A5C424F524C414E44435C494E434C5544455C5F+ 

 

?debug  C 4E46494C452E48 

 

?debug  C E9E9BB563B1B443A5C424F524C414E44435C494E434C5544455C5F+ 

 

?debug  C 4E554C4C2E48 

MAIN_TEXT 

segment byte public use16 'CODE' 

MAIN_TEXT 

ends 

DGROUP 

group 

_DATA,_BSS 

 

assume  cs:MAIN_TEXT,ds:DGROUP 

_DATA 

segment word public use16 'DATA' 

d@ 

label 

byte 

d@w 

label 

word 

_DATA 

ends 

_BSS 

segment word public use16 'BSS' 

b@ 

label 

byte 

b@w 

label 

word 

background image

_BSS 

ends 

MAIN_TEXT 

segment byte public use16 'CODE' 

 

   ; 

 

   ; 

unsigned int silnia(int n) 

   ; 

 

 

assume  cs:MAIN_TEXT 

_silnia  proc 

far 

 

push 

bp 

 

mov 

bp,sp 

 

push 

si 

// procedura _silnia typu far, położenie bp na stosie, ustawienie na nim 

//wskaźnika sp, położenie na stosie si 
 
 

 

mov 

si,word ptr [bp+6] 

   ; 

 

   ; 

// Stos: bp, si, si, cs: call _silnia, bp, si 
// wpisanie do si bp+6 czyli wartości si ze stosu przesyłanej jako parametr 
//funkcji 

 
   ; 

 

if (n<0) return -1; 

   ; 

 

 

or si,si 

 

jge 

short @1@142 

 

mov 

ax,00000FFFFh 

@1@86: 
 

jmp 

short @1@254 

 

jmp 

short @1@254 

// suma logiczna dla si; sprawdzenie czy n jest rowne 0, jeśli n większe 
//bądź równe 0 to skok do etykiety @1@142, jeśli nie to do ax wpisana 
//zostaje wartość 00000FFFFh (-1). Następnie wykonany zostaje skok 

//bezwarunkowy do etykiety @1@254 (koniec funkcji) 
 
 

@1@142: 
   ; 

 

   ; 

 

else if (n==0) return 1; 

   ; 

 

 

or si,si 

 

jne 

short @1@226 

 

mov 

ax,1 

 

jmp 

short @1@86 

 

jmp 

short @1@254 

// suma logiczna dla si, podobnie jak wyżej; jeśli n<>0 to skok do etykiety 
//@1@226, jeśli n=0 to do ax wpisana zostaje wartość 1 i wykonany skok do 
//etykiety @1@86 

 
 
@1@226: 

   ; 

 

   ; 

 

else return n * silnia(n-1); 

   ; 

 

 

mov 

ax,si 

 

dec 

ax 

 

push 

ax 

 

push 

cs 

// wpisanie do ax wartości si(zmiennej n), zmiejszenie warości ax o 1, 
//położenie ax na stosie, położenie cs na stosie, wywołanie funkcji _silnia  

 
 
 

call 

near ptr _silnia 

// STOS: bp, si, si, cs: call _silnia, bp, si, ax 
 
 

pop 

cx 

 

push 

ax 

// STOS: bp, si, si, cs: call _silnia, bp, si, ax, 
//zdjecie jednego elementu ze stosu i położenie ax 

 

background image

 

pop 

dx 

// STOS: bp, si, si, cs: call _silnia, bp, si, ax, 
 

mov 

ax,si 

// przeniesienie si do ax(n) oraz zdjecie elementu ax ze stosu do 
//dx(wartość zwrócona z procedury _silnia) 
 

 
 

imul 

dx 

// STOS: bp, si, si, cs: call _silnia, bp, si, 

// pomnożenie dx przez ax czyli n * wartość zwrócona z procedury _silnia 
 
 

jmp 

short @1@86 

// skok bezwarunkowy do @1@86 
 
@1@254: 

   ; 

 

   ; 

   ; 

 

// koniec procedury _silnia 
 
 

pop 

si 

 

pop 

bp 

 

ret 

// STOS: bp, si, si, cs: call _silnia, bp, si   

 
_silnia  endp 
// STOS: bp, si, si, 

 
 
   ; 

 

   ; 

void main(void) 

   ; 

 

 

assume  cs:MAIN_TEXT 

_main 

proc 

far 

 

push 

bp 

 

mov 

bp,sp 

 

push 

si 

   ; 

 

   ; 

//wywolanie main’a 
// STOS: bp 
// ustawienie wskaźnika stosu na bp 

// STOS: bp, si 
// si zawiera zmienna i 
 

   ; 

 

int i=3; 

   ; 

 

 

mov 

si,3 

// wpisanie do si wartości 3 
 
 

 
   ; 

 

   ; 

 

i=silnia(i); 

   ; 

 

 

push 

si 

 

push 

cs 

// położenie na stosie si, cs oraz wywołanie funkcji silnia 
 
 

call 

near ptr _silnia 

// STOS: bp, si, si, cs: call _silnia 
 
 

pop 

cx 

// STOS: bp, si, si 
// zdjecię si do cx, oraz wpisanie do si wartości zwróconej zawartej w ax 
 

 
 
 

mov 

si,ax 

// STOS: bp, si 

background image

 
   ; 

 

   ; 

 

printf("%d",i); /* jaka jest kolejnosc parametrow? */ 

   ; 

 

 

push 

si 

 

push 

ds 

 

push 

offset DGROUP:s@ 

 

call 

far ptr _printf 

// si,ds oraz offset s@ położone na stosie, wywołanie dalekie funkcji 

//_printf z biblioteki studio.h  
 
 

add 

sp,6 

// przemieszczenie wskaźnika stosu o 3 elementy wcześniej 
 
 

 
   ; 

 

   ; 

   ; 

 

 

pop 

si 

 

pop 

bp 

 

ret 

 

_main 

endp 

// koniec main’a i zdjęcie ze stosu si oraz bp 

 
 

?debug  C E9 

 

?debug  C FA00000000 

MAIN_TEXT 

ends 

_DATA 

segment word public use16 'DATA' 

s@ 

label 

byte 

 

db '%d' 

 

db 0 

_DATA 

ends 

MAIN_TEXT 

segment byte public use16 'CODE' 

MAIN_TEXT 

ends 

 

public  _main 

 

public  _silnia 

 

extrn 

_printf:far 

_s@ 

equ 

s@ 

 

end