Új hozzászólás Aktív témák

  • Sceemz

    újonc

    Sziasztok!
    A segítségeteket szeretném kérni, jelenleg egy programot írok Visual Studioban (x86 assembly). A program lényege, hogy:

    "Készítsen programot, ami a felhasználó által megadott elemszámú, véletlen számokkal feltöltött tömbben, megadja a következő statisztikai eredményeket: átlag, medián, szórás. Az eredményeket írja ki a képernyőre. Az elemszám megadását billentyűzetről kell bekérni."

    Jelenleg a kódom nagy része már kész van és az átlag, szórás számítás tökéletesen működik, visszont a medián számítás részére nem találok megoldást, ha esetleg valaki tudna benne segíteni azt nagyon meg köszöném.

    //A változók létrehozása
    int N, temp;
    int a;
    const char* hun = "Hun";
    //Setlocale
    _asm
    {
    mov temp, esp;
    //setlocale(LC_ALL, "Hun");
    //"Hun" -> LC_ALL
    push hun;
    push LC_ALL;
    call dword ptr setlocale;
    mov esp, temp;
    }
    //Véletlen szám véletlenítése
    _asm
    {
    mov temp, esp;
    push 0;
    call dword ptr time;
    push eax;
    call dword ptr srand;
    mov esp, temp;
    }
    //N bekérése
    const char* be_N = "Kérem adja meg a tömb elemszámát: ";
    const char* intformat = "%d";
    _asm
    {
    mov temp, esp;
    rossz_N:
    push be_N;
    call printf;
    lea eax, N;
    push eax;
    push intformat;
    call scanf;
    //N vizsgálata, hogy pozítiv-e
    cmp N, 0;
    jle rossz_N;
    mov esp, temp;
    }
    // Az N elemű tömb létrehozása és feltöltése véletlen számokkal
    int* A = new int[N];
    //ESP mentő változó
    int saveESP;
    _asm
    {
    mov saveESP, ESP;
    }
    //Ciklus a feltöltéshez
    _asm
    {
    mov esi, 0;
    ciklus_feltölt:
    call rand; //eax->be elteszi a rand() értékét
    mov edx, 0;
    mov ecx, 1000; // a legnagyobb kigenerált szám 1000 lehet
    div ecx;
    add edx, 1; // a legkisebb kigenerált szám az 1 lehet
    mov a, edx;
    mov eax, esi;
    mov ebx, 4;
    mul ebx;
    mov ebx, eax;
    mov edx, ebx;
    mov ecx, dword ptr A;
    add ebx, ecx;
    mov eax, a;
    mov dword ptr[ebx], eax;
    //ciklus vége
    inc esi;
    cmp esi, N;
    jl ciklus_feltölt;
    }
    const char* tomkiiras = "A feltöltött tömb: ";
    const char* sortores = "\n";
    const char* szam = "%d, ";
    int ciklusValtozo;
    // A feltöltött tömb kiírása ellenőrzésképen
    _asm
    {
    push tomkiiras;
    call printf;
    pop tomkiiras;
    // for ciklus
    mov eax, N; // N alkalommal fut le a ciklus -> ciklusváltozó
    mov ciklusValtozo, eax;
    mov esi, 0; //tömbindexhez
    ciklus:
    // tömb elemeinek kiírása
    //memóriacím kimentése változóba a dinamikus tömb eléréséhez:
    mov ebx, dword ptr[A];
    add ebx, esi; //eltolás hozzáadása a pontos helyhez
    push dword ptr[ebx]; //érték verembe helyezés
    push szam;
    call printf;
    add esi, 4; //int típus 4 bájtos
    pop szam;
    pop dword ptr[ebx];
    // tömb elemeinek kiírásának vége
    dec ciklusValtozo;
    cmp ciklusValtozo, 0;
    jne ciklus; // ha nem egyenlő az ciklusValtozo tartalma 0-val akkor folytatódi a ciklus
    // for ciklus vege
    push sortores;
    call printf;
    pop sortores;
    }
    // Átlag kiszámítása
    float osszeg = 0.0;
    float atlag = 0.0;
    //A tömb átlaga
    _asm
    {
    mov esi, 0;
    ciklus_atlag:
    //index kiszámítás
    mov eax, esi;
    mov ebx, 4; // mivel int típusú tömbünk van, 4 byte méretű elemekkel dolgozunk
    mul ebx;
    mov ebx, eax; //i*4 kerül az ebx-be
    //-b
    mov edx, ebx;
    mov ecx, dword ptr A;
    add ebx, ecx;
    fild dword ptr[ebx]; // fild az integer értéket betölti a FPU regiszterbe
    fld osszeg;
    fadd;
    fstp osszeg;
    //ciklus vége
    inc esi;
    cmp esi, N;
    jl ciklus_atlag;
    fld osszeg;
    fidiv N;
    fstp atlag;
    }
    // Átlag kiíratása
    const char* atlagText = "Átlag: ";
    const char* atlagFormat = "%.1f\n";
    _asm
    {
    mov eax, dword ptr[atlagText];
    push eax;
    call printf;
    add esp, 4;
    fld atlag; // az átlag értékének betöltése a lebegőpontos regiszterbe
    sub esp, 8; // hely foglalása a veremben a kiíratáshoz
    fstp qword ptr[esp]; // az átlag értékének a veremre helyezése
    push dword ptr[atlagFormat];
    call printf;
    add esp, 12; // a hely felszabadítása a veremben
    }
    // Medián kiszámítása
    float median;
    _asm
    {
    mov ecx, N; // ecx-be betöltjük a tömb méretét
    mov ebx, 2; // ebx-be betöltjük az 2-es értéket, hogy megkaphassuk a tömb középső elemét
    cdq; // eax regisztert bővíti edx regiszterrel
    idiv ebx; // az N-t osztjuk 2-vel, az eredmény az eax-ben lesz, a maradék pedig az edx-ben
    mov edx, 0; // az edx-t nullázzuk, hogy ne maradjon benne az osztás eredménye
    cmp edx, 0; // összehasonlítjuk a maradékot 0-val, hogy megállapítsuk, páros vagy páratlan a tömb mérete
    je paros_meret; // ha a maradék 0, akkor a tömb mérete páros
    // Ha a tömb mérete páratlan, a medián az N/2. elem lesz
    mov ebx, N; // ebx-be betöltjük a tömb méretét
    mov eax, ebx; // az N-t mozgatjuk az eax-be
    sar eax, 1; // az N-et osztjuk 2-vel, az eredmény az eax-ben lesz
    mov ebx, eax; // az eredményt áttesszük a ebx-be
    mov edx, 0; // az edx-t nullázzuk
    mov eax, dword ptr A[ebx * 4]; // az N/2. elemet betöltjük az eax-be
    jmp kiir; // ugorjunk a kiíratáshoz
    paros_meret:
    // Ha a tömb mérete páros, a medián az N/2. és (N/2)+1. elem átlaga
    mov ebx, N; // ebx-be betöltjük a tömb méretét
    mov eax, ebx; // az N-t mozgatjuk az eax-be
    sar eax, 1; // az N-et osztjuk 2-vel, az eredmény az eax-ben lesz
    mov ecx, eax; // az eredményt áttesszük a ecx-be
    add eax, 1; // az N/2-hez hozzáadjuk 1-et, az eredményt az eax-be tesszük
    mov edx, 0; // az edx-t nullázzuk
    mov ebx, dword ptr A[ecx * 4]; // az N/2. elemet betöltjük a ebx-be
    add ebx, dword ptr A[eax * 4]; // az (N/2)+1. elemet hozzáadjuk a ebx-hez
    mov eax, ebx; // az eredményt áttesszük az eax-be
    sar eax, 1; // az összeget osztjuk 2-vel, az eredmény az eax-ben lesz
    kiir:
    movsd median, xmm0; // az eredményt áttesszük a median változóba
    }
    // Medián kiíratása:
    cout << "Medián: " << fixed << setprecision(2) << median << endl;
    // Szórás kiszámítása
    float standardDeviation = 0.0;
    float variance = 0.0;
    int ezzelosztunk = N; // Módosítás: az ezzelosztunk változó értéke N lesz, mert a szórás számításánál N-el osztunk, nem N-1-gyel
    _asm
    {
    // for ciklus
    mov eax, N; // N alkalommal fut le a ciklus -> ciklusváltozó
    mov ciklusValtozo, eax;
    mov esi, 0; //tömbindexhez
    szoras_ciklus:
    mov ebx, [A];
    add ebx, esi; //eltolás hozzáadása a pontos helyhez
    fild[ebx];
    fld atlag;
    fsub st(1), st(0); // kivonjuk a generált számból az átlagot
    fxch st(1); // st(1)-ben lévő eredményt átrakjuk st(0)-ba
    fstp st(1); // st(1)-ben lévő értéket kiszedjük (töröljük)
    fmul st(0), st(0); // st(0)-ban lévő értékét megszorozzuk önmagával (négyzetre emelés)
    fadd variance; // a variance-hez hozzáadjuk az eredményt
    fstp variance; // az eredményt elmentjük a variance-ba
    add esi, 4; //int típus 4 bájtos
    dec ciklusValtozo;
    cmp ciklusValtozo, 0;
    jne szoras_ciklus; // ha nem egyenlő az ciklusValtozo tartalma 0-val akkor folytatódi a ciklus
    // ciklus vége
    fld variance; // betöltjük st(0)-ba a variance változó értékét
    fidiv ezzelosztunk; // elosztjuk az st(0)-ban lévő értéket N-nel
    fsqrt; // gyökvonás
    fstp standardDeviation; // az st(0)-ban lévő értéket eltároljuk a standardDeviation változóban
    }
    // Szórás kiíratása:
    const char* standardDeviationText = "Szórás: ";
    const char* standardDeviationFormat = "%.1f\n";
    _asm
    {
    mov eax, dword ptr[standardDeviationText];
    push eax;
    call printf;
    add esp, 4;
    fld standardDeviation; // a szorás értékének betöltése a lebegőpontos regiszterbe
    sub esp, 8; // hely foglalása a veremben a kiíratáshoz
    fstp qword ptr[esp]; // a szórás értékének a veremre helyezése
    push dword ptr[standardDeviationFormat];
    call printf;
    add esp, 12; // a hely felszabadítása a veremben
    }
    delete[] A; // Dynamikusan allo tomb memoria felszabaditasa
    return 0;
    }

Új hozzászólás Aktív témák