Zespół: PT/17/TP Wrocław, 07.05.2010
Elżbieta Tchorowska, 171067
Konrad Kukulski, 163930
Ocena:
Oddano:
Moduł as w programach C na platformie Linux
Sprawozdanie z laboratorium z przedmiotu „Architektura Komputerów”
Rok. Akadem. 2009/2010, Kierunek: INF
PROWADZĄCY:
Mgr inż. Mariusz Czapski
Spis treści:
Cel ćwiczenia
Celem ćwiczenia było zapoznanie się z systemem MMX. Wg polecenia należało wczytać obrazek *.bmp oraz wykonać na nim operacje odbicia lustrzanego oraz rozmycia.
Przebieg ćwiczenia
Wygląd pliku Makefile, pomija się i przyjmuje, że jego działanie jest wiadome. Działanie programu zostało podzielone na dwie części. Jedna została napisana jako plik asemblera, druga jako plik C. Użyto modułu C w asemblerze.
Algorytm
Pierwszym krokiem było stworzenie pliku z rozszerzeniem .c, który zawierałby odniesienie do funkcji pisanej w asemblerze:
Plik zawiera odniesienie do eksportowanej funkcji lustro. W założeniach, w C zostanie napisane wczytywanie pliku graficznego, deklaracja tablic alokowanych dynamicznie, oraz przeniesienie bitów obrazka do tablic.
Asembler ma za zadanie utworzyć lustrzane odbicie wykorzystując MMX i przesłać obrazek z powrotem do C, który plik zapisze.
Program C.
Pełny program napisany w C wyglądał następująco:
Program as.
Ustalono, jak powinien wyglądać ogólny zarys programu as i importowanie zmiennych do drugiego środowiska. Ogólną strukturę i formę zapisu podejrzano ze strony http://rudy.mif.pg.gda.pl/~bogdro/linux/index.php i wykorzystano ją w działaniu programu.
Program wykonany poprawnie, kompilujący się.
Główny program w asemblerze
Program wyglądał następująco:
Wnioski
Niestety program nie działał poprawnie. Obraz wynikowy wychodził co najmniej dziwny, przedstawiający pokratkowany, kolorowy obszar. Nie znaleziono przyczyny błędu, choć domniemywa się, że problem polega w odkładaniu wartości na stos. Nie sprawdzono dokładności tej hipotezy.
Strona 1 z 4
#include <stdio.h>
#include <stdlib.h>
extern void lustro(char a, char b);
{
return(0);
}
SYSEXIT = 1
EXIT_SUCCESS = 0
.align 32
.data
.global lustro //wywołanie funkcji globalnej
lustro:
temp1: .byte 0xAA //utworzenie zmiennej byte
movb 8*(%ebp), %bl //8, 12 - podbranie z modułu
movb 12*(%ebp), %bl
push %ebp //odłożenie na stos wczytywanych
mov %esp,%ebp //wartości z modułu
mov %ebp, temp1
movb 8*(%edx), %al //przepisanie do akumulatora
movb 12*(%edx),8*(%edx)
movb %al, 12*(%edx)
movb 12*(%edx), %al
mov %ebp,%eax
leave
ret
mov $SYSEXIT, %eax
mov $EXIT_SUCCESS, %ebx
int $0x80
#include <stdio.h>
#include <stdlib.h>
extern void lustro(char a, char b); //funkcja eksportowana
void asmm(char * tab1, char * tab2, int a, int b)
{
tab2[a]=tab1[b]; //przypisanie dwóch tablic
} //dynamicznych
int main(int argc, char *argv[])
{
int i,j;
FILE *f1 = fopen("aaa.bmp", "rb"); //otwarcie pliku do odczytu
FILE *f2 = fopen("bbb.bmp", "wb"); //otwarcie dwóch plików
FILE *f3 = fopen("ccc.bmp","wb"); //do zapisu
fseek (f1 , 0 , SEEK_END);
int n = ftell (f1);
fseek (f1 , 0 , SEEK_SET);
char *tab1 = (char*) malloc (sizeof(char)*n); //utworzenie trzech tablic
char *tab2 = (char*) malloc (sizeof(char)*n); //do umieszczenia bitów
char *tab3 = (char*) malloc (sizeof(char)*n); //obrazka
fread(tab1, 1, n, f1); //wczytanie obrazka do tab.
for(i=0;i<54;i++){tab2[i]=tab1[i];}
for(i=0;i<600;i++)
{
for(j=0;j<865;j=j+2) //lustro
{
lustro(&tab2[(i*865*3+i)+(865*3)-(j*3)+54],&tab1[(i*865*3+i)+(j*3)+54]);
}
}
fwrite(tab2, 1, n, f2); //zapis do tablicy 2 i 3
fwrite(tab3, 1, n, f3);
fclose(f1); //zamknięcie strumieni
fclose(f2);
fclose(f3);
return(0);
}