mmx assembly

Sziasztok!

Az alabbi pici fugvenyt kene mmx hasznalataval assemblybe megirnom (iskolai feladat, es egy ideje szenvedek vele, de sehogy nem megy).


void Filter(unsigned char * buf, int width,int height,char bpp) {
	int i,j,tmp;
	for (i=0;i<height*bpp;i++) {  // wirsze 
		for (j=0;j<width;j++) { // kolumny
			tmp=buf[i*width+j];
		        buf[i*width+j]=(unsigned char)(~(tmp));
		}
	}
}

a legnagyobb problemam mar a kezdet kezdetenel a negalasnal jelentkezik, mivel elvileg nincs ilyen utasitas az mmx utasitas keszletben.

Koszi

Hozzászólások

hat akkor pxor-oljal 0xffffffffffffffff-fel.

- Use the Source Luke ! -

Szerintem nem kellene minden egyes utasitasnak MMX utasitasnak lennie.

tobb sebbol verzik a megoldas, mint pl. hogy nem kell se
a leal se a ket movq, azonkivul ertelmesebb kezdoertekekkel (pl. hogy
a sor vegerol kezded a feldolgozast) a cmp-t is lehet eliminalni.
amugy sem ertem miert kene megirni mas hazi feladatat.

- Use the Source Luke ! -

igen oktatasi pelda, eled raktak, hogy tessek old meg, fv-t mar irtal assemblyben (igen csak az egy picit egyszerubb volt, de azzal is kellett szenvedni) aztan emg azt mondja ott van intel utasitaslapja pdfben ird at ezt a fv-t a programbol aassemblyben mmx hasznalosra, vagy legalabb : buf[i*width+j]=(unsigned char)(~(tmp));
Ha mondom koszi, talan vmit magyarazni, vayg valami hogy megis hogyan, de semmi, orat vegig google, hogy legalabb valahonnan elinduljak, aztan itthon is google, de az istenert meg elindulni sem tudok semerre.
Szoval vegso ketsegbe esesemben fordultam hozzatok, bar tudom hogy baromira nem nektek kell megoldani a hazi feladatomat. Csakhat ehhez egesz egyszeruen hulye vagyok, de sakjnos meg kell csinalni.

Vagy osszezavarja a tanart :)
Anno nekunk vizsgan kellett egy faktorialis szamolot irni assemblyben. Allitolag (en nem jartam be orara:)) evkozben a tanar felirt valami kb 20 soros megoldast, es gondolom azt varta, hogy azt majd bemagolja mindenki.
Na most vizsgan en megirtam ennyibol:

mov eax,1
mov ecx,N
x: imul eax,ecx
loop x
mov N,eax

a tanar ravagta hogy ez nem jo. mondom, de jo. de nem. de de. na probaljuk ki. kiprobaltuk, mukodik. masik ertekkel is. harmadikkal is. de a tanar szerint ez akkor sem jo, mert o nem ezt tanitotta. aztan elmagyaraztam neki lepesrol lepesre hogy mukodik, vegul elfogadta nagy nehezen.

szoval ovatosan az optimalizalassal, mert meg a vegen tul jol sikerul :)

A'rpi

igen az ilyen tanarokat en is nagyon szeretm. Viszont az en megoldasom meg mindig nem mukodik, mostmar odaig fajultam hogy fogtam magam, es atirtam egy picit a gcc altal generalt kodot, csak ez nem tudom hogy igy mennyire mmx kihasznalasa. Raneznetek:


.globl Filter
	.type	Filter, @function
Filter:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$20, %esp
	movl	20(%ebp), %eax
	movb	%al, -20(%ebp)
	movl	$0, -4(%ebp)

.L3:
	movl	$0, -8(%ebp)
	movl	-8(%ebp), %eax
.L5:
	movl	-4(%ebp), %eax
	imull	12(%ebp), %eax
	addl	-8(%ebp), %eax
	addl	8(%ebp), %eax
	movzbl	(%eax), %eax
	movzbl	%al, %eax
	movl	%eax, -12(%ebp)
	movl	-4(%ebp), %eax
	imull	12(%ebp), %eax
	addl	-8(%ebp), %eax
	movl	%eax, %edx
	addl	8(%ebp), %edx
	movq	-12(%ebp), %mm0     #innen mmx
	movl 	$0xffffffff, %esi
	movd	%esi, %mm1
	pxor 	%mm1, %mm0
	movd 	%mm0, %eax          #idaig mmx
	movb	%al, (%edx)
	addl	$1, -8(%ebp)
	movl	-8(%ebp), %eax
	cmpl	12(%ebp), %eax
	jl	.L5
	addl	$1, -4(%ebp)
	movsbl	-20(%ebp),%eax
	imull	16(%ebp), %eax
	cmpl	-4(%ebp), %eax
	jg	.L3
	leave
	ret

ismet a segitsegetek szeretnem kerni, jelnleg itt jarok:


.section .text
.globl Filter
	.type	Filter, @function
Filter:
 pushl %ebp           
 movl %esp, %ebp      
 imull %ecx, %ebx
 movl  16(%ebp), %ecx 
 imull %ebx, %ecx  	#width*height*bpp
 movl $0xffffffff, %esi
 movd %esi, %mm1
 
loop:
movq (%eax), %mm0
pxor %mm1, %mm0
movq %mm0, (%eax)
addl $8, %edx
cmpl %edx, %ecx
jg loop
 movl %ebp, %esp      
 popl %ebp           
 ret

igy lefordul, de azonkivul h kiirja h lefotutott nem csinal semmit.

es termeszetesen itt van a hozzatartozo kod is, amiben a fv szerepel:


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "SDL.h"
#include "SDL_image.h"

SDL_Surface* Load_image(char *file_name)
{
		SDL_Surface* tmp = IMG_Load(file_name);
		if ( tmp == NULL ) {
			fprintf(stderr, "Couldn't load %s: %s\n",
			        file_name, SDL_GetError());
				exit(0);
		}
		return tmp;	
}

void Paint(SDL_Surface* image, SDL_Surface* screen)
{
		SDL_BlitSurface(image, NULL, screen, NULL);
		SDL_UpdateRect(screen, 0, 0, 0, 0);
};



void Filter(unsigned char * buf, int width,int height,char bpp);
int main(int argc, char *argv[])
{
	Uint32 flags;
	SDL_Surface *screen, *image;
	int depth, done;
	SDL_Event event;
	/* Initialize the SDL library */
	if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
		fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
		return(255);
	}

	flags = SDL_SWSURFACE;
	image = Load_image( "2.bmp" );
	printf( "\n\nImage properts:\n" );
	printf( "BitsPerPixel = %i \n", image->format->BitsPerPixel );
	printf( "BytesPerPixel = %i \n", image->format->BytesPerPixel );
	printf( "width %d ,height %d \n\n", image->w, image->h );	 	
	SDL_WM_SetCaption(argv[1], "showimage");
	/* Create a display for the image */
	depth = SDL_VideoModeOK(image->w, image->h, 32, flags);
	if ( depth == 0 ) {
		if ( image->format->BytesPerPixel > 1 ) {
			depth = 32;
		} else {
			depth = 8;
		}
	} else
	if ( (image->format->BytesPerPixel > 1) && (depth == 8) ) {
    		depth = 32;
	}
	if(depth == 8)
		flags |= SDL_HWPALETTE;
	screen = SDL_SetVideoMode(image->w, image->h, depth, flags);
	if ( screen == NULL ) {
		fprintf(stderr,"Couldn't set %dx%dx%d video mode: %s\n",
			image->w, image->h, depth, SDL_GetError());
	}

	/* Set the palette, if one exists */
	if ( image->format->palette ) {
		SDL_SetColors(screen, image->format->palette->colors,
	              0, image->format->palette->ncolors);
	}


	/* Display the image */
	Paint(image, screen);

	done = 0;
	while ( ! done ) {
		if ( SDL_PollEvent(&event) ) {
			switch (event.type) {
			    case SDL_KEYUP:
				switch (event.key.keysym.sym) {
				    case SDLK_ESCAPE:
				    case SDLK_TAB:
				    case SDLK_q:
					done = 1;
					break;
				    case SDLK_SPACE:
				    case SDLK_f:
					SDL_LockSurface(image);
					
					printf("Start filtering...  ");
					Filter(image->pixels,image->w,image->h, image->format->BytesPerPixel );
					printf("Done.\n");

					SDL_UnlockSurface(image);
					
					printf("Repainting after filtered...  ");
					Paint(image, screen);
					printf("Done.\n");
					
					break;
				    case SDLK_r:
					printf("Reloading image...  ");
					image = Load_image( argv[1] );
					Paint(image,screen);
					printf("Done.\n");
					break;
				    case SDLK_PAGEDOWN:
				    case SDLK_DOWN:
				    case SDLK_KP_MINUS:
					printf("Aktual size is:\n");
				        break;
				    case SDLK_PAGEUP:
				    case SDLK_UP:
				    case SDLK_KP_PLUS:
					printf("Aktual size is:");
					break;		
				   case SDLK_s:
					printf("Saving surface at nowy.bmp ...");
					SDL_SaveBMP(image, "nowy.bmp" ); 
					printf("Done.\n");
				    default:
					break;
				}
				break;
                            case SDL_QUIT:
				done = 1;
				break;
			    default:
				break;
			}
		} else {
			SDL_Delay(10);
		}
	}
	SDL_FreeSurface(image);
	SDL_Quit();
	return(0);
}

Figyelj. Ha valami egyszerut akarsz tesztelni, ne irj bonyolult tesztprogit hozza. Csinajl egy alap c fajlt, amibe se sdl, se semmi nincs, csak generalsz a bufba valami fals ertekeket, es a vegen kiirod a kimenetet. Ne erdekeljen, hogy a buf micsoda, a w a h micsoda, semmi, csak a szamolas. Ha ugy mukodik, akkor elkepzelheto, hogy a SDL-es programban is mukodni fog. De azt felejtsd el, hogy rogton elesben tesztelsz egy olyan modult, amirol azt sem tudod, mukodik-e.