Programowanie niskopoziomowe
Sprawozdanie
Laboratorium 4
Funkcje rekurencyjne i biblioteczne
Wykonujący:
Paweł Ochał
Grzegorz Róg
Jacek Pieprzak
L04
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
_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
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
;
;
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