Assembler opdracht: 15 karakters alfabetiseren

Pagina: 1
Acties:
  • 230 views sinds 30-01-2008
  • Reageer

  • Aham brahmasmi
  • Registratie: Juni 2002
  • Laatst online: 21-12-2025
Ik heb voor school een opdracht gekregen om assembly een programma te schrijven waarin een regel van 15 karakters op alfabetische volgorde geplaatst wordt. Het programma dient geschreven te worden in een tekstbestand (notepad oid) en met Turbo Assembler (TASM en TLINK) gecompileerd te worden en in Turbo Debugger uitgevoerd (om te demonstreren dat het werkt).

Nu hoop ik dat iemand mij hier een beetje op weg kan helpen. Ik heb al eens een programmaatje geschreven dat namen van vier letters op alfabetische volgorde kan zetten. Ik weet alleen niet hoe ik een regel van 15 karakters kan invoeren.

Kan iemand aanwijzingen geven hoe het volgende programma aangepast zou kunnen worden om een regel van 15 karakters te alfabetiseren??

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
        .MODEL small    ;
        .STACK 100h     ;
        .DATA           ;
Naam1    DB 'vuur'      ;1e naam
Naam2    DB 'roos'      ;2e naam
        .CODE           ;
        mov ax,@data    ;
        mov ds,ax       ;
        mov bx,0000     ;Adres eerste letter in BX
                        ;
        call wissel     ;Roep subroutine wissel aan
        mov ah,4ch      ;(Als het wisselen klaar is,
        int 21h         ; terug naar DOS.)
wissel: push ax         ;Zet register op stack
        push bx         ;      "
        push cx         ;      "
        mov cx,0004     ;Laad teller met aantal letters = 4
    mov dx,0000 ;Initialisatie (gaat er van uit dat
            ; er niet gewisseld hoeft te worden)
    mov [bx],ah     ;Zet AH in BX
        mov [bx+04],al  ;Zet AL in BX+4
next:   mov al,[bx]     ;Laad karakterpointer 1e naam in AL
            ; = (BX)-ste letter van 1e naam 
        mov ah,[bx+04]  ;Laad karakterpointer 2e naam in AL
            ; = (BX)-ste letter van 2e naam
        cmp al,ah       ;Vergelijk AL en AH
            ; (als AL-AH != 0, dan volgende regel)
hoger:  jb next     ;Volgende 2 letters vegelijken als 2e<1e
    ja exec     ;Wisselen als 2e>1e
        inc bx      ;Teller voor volgende letters verhogen
        dec cx      ;Teller voor het aantal letters verlagen
exec:   mov dx,01       ;Zet parameter voor wisselen
        jne next        ;Volgende letters
    jmp next    ;Volgende letters vergelijken
next:   pop cx          ;Registers herstellen
        pop bx          ; met oude waarde van stack
        pop ax          ;
        ret         ;Terug naar hoofdprogramma
        END     ;Einde programma

[ Voor 17% gewijzigd door Aham brahmasmi op 06-01-2003 13:22 ]


  • EfBe
  • Registratie: Januari 2000
  • Niet online
Welke school geeft zn leerlingen nu een sorteeropdracht in assembler... :)

Anyway, de opdracht is er om je iets te leren. Hier het antwoord ophalen leert je niks en je sjeest dan geheid voor het tentamen. Beter is wat extra tijd te steken in het doornemen van de boeken en wellicht het diktaat en dan proberen, nadenken etc.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • Solomon
  • Registratie: December 2001
  • Laatst online: 08:05
Ik geloof dat je geen huiswerkvragen mag posten hier ;)

V&A aangeboden: LSI 9207-8i (IBM M5110) geflashed naar IT MODE


  • whoami
  • Registratie: December 2000
  • Nu online
Venkeroz schreef op 06 January 2003 @ 13:08:
Ik geloof dat je geen huiswerkvragen mag posten hier ;)


Check de FAQ nogeens. (Trouwens, die Topicreports worden ook wel gelezen hoor ;).
Het is toegestaan om huiswerk te plaatsen. Mits het aan een aantal eisen voldoet.

Je geeft duidelijk een beschrijving van je opdracht en je probleem.

Je geeft ook duidelijk aan wat je al geprobeerd hebt.

Je moet niet vergeten dat je het huiswerk hoort te kunnen maken met alleen je studiemateriaal en de eventuele hulp van docenten/assistenten en medestudenten.

Zodra de vraag richting "maken jullie het dan even" gaat, dan gaat je topic zonder meer op slot.

Verder gelden natuurlijk ook hiervoor de standaard voorwaarden uit de algemene en subforum faq.
Die TR's zijn er trouwens om posts zoals de jouwe te voorkomen. Je kan zo'n dingen nl. kwijt in een topicreport of in 'Schop een modje'

[ Voor 43% gewijzigd door whoami op 06-01-2003 13:18 ]

https://fgheysels.github.io/


Verwijderd

Is dit een voorbeeld wat je zelf al hebt gemaakt? D'r zijn namelijk nogal wat rariteitjes aan vind ik zelf...
Maar als je invoer wilt kunnen gebruiken, kun je het beter (deels) in C schrijven, of je verder gaan verdiepen in dos-interrupts in assembly, maar daar zie ik niet echt het nut van in voor "een" opleiding... Je zou de functie i.e.g. moeten aanpassen, bijvoorbeeld om drie argumenten van de stack te plukken (adres van stringetje 1, adres van stringetje 2, en lengte van stringetjes)

  • Aham brahmasmi
  • Registratie: Juni 2002
  • Laatst online: 21-12-2025
Ik vraag toch niet of men het hier voor mij wil voorkauwen?! Ik hoopte gewoon dat er hier iemand is die behulpzaam is en mij misschien een paar tips/aanwijzingen kan geven.

Het is trouwens de TH Rijswijk die mij deze opdracht geeft, voor het vak Microcomputertechniek (mijn studie=Technische Natuurkunde). Dat vak wordt niet meer gegeven, maar ik had het nog niet gehaald en moet er dus nog een opdracht voor maken. Of ik nu hier hulp vraag of bij m'n docent maakt weinig verschil lijkt mij.

Edit: Dazaffiro: Ik mag het niet in C schrijven, en ik hoef de letters ook niet in te voeren. Ze komen gewoon als string in het programma te staan, en als je het stap voor stap in Turbo Debugger uitvoert zie je de letters van plaats verwisselen tot alles op alfabetische volgorde staat.

[ Voor 24% gewijzigd door Aham brahmasmi op 06-01-2003 13:34 ]


  • whoami
  • Registratie: December 2000
  • Nu online
Thermo man schreef op 06 januari 2003 @ 13:30:
Ik vraag toch niet of men het hier voor mij wil voorkauwen?! Ik hoopte gewoon dat er hier iemand is die behulpzaam is en mij misschien een paar tips/aanwijzingen kan geven.

Het is trouwens de TH Rijswijk die mij deze opdracht geeft, voor het vak Microcomputertechniek (mijn studie=Technische Natuurkunde). Dat vak wordt niet meer gegeven, maar ik had het nog niet gehaald en moet er dus nog een opdracht voor maken. Of ik nu hier hulp vraag of bij m'n docent maakt weinig verschil lijkt mij.


Relax.... Ik denk dat de vraag of dit topic hier wel of niet thuishoort enzo reeds lang beantwoord is....

Misschien een idee om verder on-topic te gaan ipv daarover te neuzelen.
Die post van EfBe was volgens mij trouwens eerder sarcastisch bedoeld.

https://fgheysels.github.io/


  • EXX
  • Registratie: Juni 2001
  • Laatst online: 25-08 23:09

EXX

EXtended eXchange

Om een string te kunnen invoeren is het idd het makkelijkste om een DOS functie of een eventueel een BIOS functie te gebruiken.


Neem bv. BIOS interrupt 16H, functie 00H. Daarmee kun je tekens inlezen.

code:
1
2
mov ah,00            ;functie 00 uitvoeren = teken lezen
int   16h            ;interrupt uitvoeren

resultaat in ah is dan de scancode van de toest, al bevat de ASCII code.

Een lusje maken voor 15 tekens en klaar.

Nog een kleine hint. Gebruik voor het maken van loops het CX register. Dan kun je de speciale loop instructies gebruiken die werken met CX, bv:

code:
1
loop     label


Deze instructie doet hetzelfde als:

code:
1
2
dec    cx
jne    label

[ Voor 30% gewijzigd door EXX op 06-01-2003 13:48 ]

For it is the doom of men that they forget...           Huidige en vroegere hardware specs         The Z80 is still alive!


Verwijderd

Thermo man schreef op 06 January 2003 @ 13:30:
Edit: Dazaffiro: Ik mag het niet in C schrijven, en ik hoef de letters ook niet in te voeren. Ze komen gewoon als string in het programma te staan, en als je het stap voor stap in Turbo Debugger uitvoert zie je de letters van plaats verwisselen tot alles op alfabetische volgorde staat.
Oke, dat scheelt.

Maar ik vind het nogal raar dat je ax/bx/cx op de stack zet, wat zijn daar je motieven voor?

In elk geval moet je dus gaan opsporen waar in dit programma de beginadres van Naam1 en Naam2 in het algoritme wordt opgevraagd en de lengte. Probeer dat eens variabel te maken, door elk van de labels te moven naar een register *ergens* i.p.v. een hardgecodeerde waarde en voor de lengte een "equ" te gebruiken ("length equ 15" en dan "length" verwerken in je code).

En een "jne next" gevolgd door een "jmp next" doet me afvragen of je weet wat je doet en waarom me dat nu pas opvalt :? En d'r zijn twee "next" labels :?

[ Voor 31% gewijzigd door Verwijderd op 06-01-2003 14:21 ]


  • EfBe
  • Registratie: Januari 2000
  • Niet online
whoami schreef op 06 januari 2003 @ 13:32:
Misschien een idee om verder on-topic te gaan ipv daarover te neuzelen.
Die post van EfBe was volgens mij trouwens eerder sarcastisch bedoeld.
Indeed, want ik zie het nut van het leren van assembler nog wel in, maar gebruik dan een opdracht die dichter bij het toepassingsgebied ligt van assembler. Sorteren doe je t.a.t. niet in assembler, het is nogal lastig implementeren, zo'n algoritme met recursie ;)

TS: als je eerst een sorteeralgoritme uitkiest, liefst 1 die niet gebruik maakt van recursie, dan kun je daarna dat algoritme omzetten in code. Dat lijkt me niet zo heel lastig.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • EXX
  • Registratie: Juni 2001
  • Laatst online: 25-08 23:09

EXX

EXtended eXchange

EfBe schreef op 06 January 2003 @ 14:35:
[...]

Indeed, want ik zie het nut van het leren van assembler nog wel in, maar gebruik dan een opdracht die dichter bij het toepassingsgebied ligt van assembler. Sorteren doe je t.a.t. niet in assembler, het is nogal lastig implementeren, zo'n algoritme met recursie ;)

TS: als je eerst een sorteeralgoritme uitkiest, liefst 1 die niet gebruik maakt van recursie, dan kun je daarna dat algoritme omzetten in code. Dat lijkt me niet zo heel lastig.
Bubblesort bv. Is zowat het traagste algoritme wat er is, maar het gebruikt geen recursie en is erg straightforward, dus makkelijk te implementeren in asm.

For it is the doom of men that they forget...           Huidige en vroegere hardware specs         The Z80 is still alive!


  • Aham brahmasmi
  • Registratie: Juni 2002
  • Laatst online: 21-12-2025
Verwijderd schreef op 06 januari 2003 @ 14:13:
[...]

En een "jne next" gevolgd door een "jmp next" doet me afvragen of je weet wat je doet en waarom me dat nu pas opvalt :? En d'r zijn twee "next" labels :?
Ow... dat zag ik ook al, en nu pas concludeer ik dat het foutjes in copy/paste-werk zijn. Ik heb een aantal .asm bestandjes die ongeveer hetzelfde doen, en ik ben even aan het uitzoeken welke werkt, en waar het duidelijkste commentaar bij staat. Ik edit m'n eerste post met de code straks wel zodat het geheel klopt.

(Wel klote trouwens dat tlink niet werkt onder winxp (TD werkt wel); moe'k weer naar win98 :Z .)

  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 12:20

Tomatoman

Fulltime prutser

Thermo man schreef op 06 januari 2003 @ 13:30:
Het is trouwens de TH Rijswijk die mij deze opdracht geeft, voor het vak Microcomputertechniek (mijn studie=Technische Natuurkunde). Dat vak wordt niet meer gegeven, maar ik had het nog niet gehaald en moet er dus nog een opdracht voor maken. Of ik nu hier hulp vraag of bij m'n docent maakt weinig verschil lijkt mij.
Dat komt mij erg bekend voor. Is die fossiel Van de N. nog steeds niet met pensioen? Volgens mij is zijn lesmateriaal de laatste 30 jaar niet meer veranderd. Niet dat ik kwaad over hem denk hoor O-)

Als je de snelle weg wilt nemen, schrijf je de applicatie gewoon in bijvoorbeeld Delphi of C++. CPU-venster openen, assemblercode kopiëren en klaar is Thermo man >:)

Een goede grap mag vrienden kosten.


  • Aham brahmasmi
  • Registratie: Juni 2002
  • Laatst online: 21-12-2025
Het lijkt mij er op dat van de N. nu wel met pensioen is... daarom wordt het vak waarschijnlijk niet meer gegeven. Vorig jaar had ik nog wel les van hem. Ik heb de opdracht nu van dhr. Lb gekregen, die trouwens ook de lessen van ELN (Elektrische Netwerken) aan P-studenten heeft overgenomen van v/d N..

Ik heb er wel heel even over gedacht om het programmaatje in C te schrijven, maar ik weet niet of het programma dan nog wel 'leesbaar' genoeg is voor mij, want ik moet de werking namelijk kunnen uitleggen. Ik kan het iig nog even proberen.

  • xoror
  • Registratie: November 1999
  • Niet online
je kan een string gewoon zien als een reeks nummers die je kan sorteren.

wat je kan doen is een zogenaamde frequentie table bij houden. Aan de hand van die table kan je je resultaat genereren. het is een variant op bucketsort en heel eenvoudig te maken in ASM.

in C code.


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#define MAXRES 15
#define CHARALF 256

int main(int argc, char* argv[])
{

    char sortstring[] = "sorTeerMijAuB";
    char resultaat[MAXRES + 1];
    int freqtable[CHARALF];
    int i, res_idx;
    unsigned char c;

    // init frequentie table
    for (i=0; i < CHARALF; i++)
        freqtable[i] = 0;

    // chars tellen, dus maar 1 x je string doorlopen
    for (i=0; i < strlen(sortstring); i++) {
        c = sortstring[i];
        freqtable[c]++;
    }

    //resultaat maken
    res_idx = 0;
    for (i < 0; i< CHARALF; i++) {
        if (freqtable[i] > 0) {
            // char met index i is aanwezig.
            while (freqtable[i] > 0) {
                resultaat[res_idx] = i;
                freqtable[i]--;
                res_idx++;
            }
        }
    }
    resultaat[res_idx] = '\0';

    printf("before sort: %s\n", sortstring);
    printf("after sort: %s\n", resultaat);

    return 0;
}


draaien geeft
before sort: sorTeerMijAuB
after sort: ABMTeeijorrsu

[ Voor 40% gewijzigd door xoror op 07-01-2003 14:52 . Reden: geteste code bijgedaan ]

Mitsubishi Warmtepomp Uitlezen / Besturen | Optimaliseren


  • Aham brahmasmi
  • Registratie: Juni 2002
  • Laatst online: 21-12-2025
Hmm... jij bent zo te zien iets verder met C dan ik. :) Ik snap het meeste wel, alleen heb ik nog niet met char's gewerkt. Werkt dit trouwens zonder additionele libraries (alleen stdio.h)?

In welk programma compileer je je C prog trouwens? Ik heb de afgelopen weken een beetje met DevC++ 4 (Bloodshed software) gewerkt, maar daarmee kreeg ik bij simpele programmaatjes met 2 for loops erin al rare fouten, zelfs bij programma's die ik letterlijk uit de antwoorden van mijn schoolboek van C heb overgenomen. Ik heb ook Borland C++ Builder 5.0 nogwat, maar ik heb weinig zin om dat te installeren omdat m'n harddisk er zo vol van raakt (5000 bestanden in totaal en 300+ MB geloof ik).

  • xoror
  • Registratie: November 1999
  • Niet online
Thermo man schreef op 07 January 2003 @ 23:48:
Hmm... jij bent zo te zien iets verder met C dan ik. :) Ik snap het meeste wel, alleen heb ik nog niet met char's gewerkt. Werkt dit trouwens zonder additionele libraries (alleen stdio.h)?
de source die ik gepaste heb werkt gewoon, je hoeft geen extra dingen te includen. ik heb het alleen even snel in C gemaakt omdat ik het dan snel kon testen. Als je het algoritme snapt kan je dit heel eenvoudig in ASM implementeren. Zoals je ziet doorloop je je string maar 1 keer. Bij hele grote input is dit dus supersnel vergeleken met bijv. bubble sort.

Het unsigned char type is niets anders dan een byte in dit geval.
In welk programma compileer je je C prog trouwens? Ik heb de afgelopen weken een beetje met DevC++ 4 (Bloodshed software) gewerkt, maar daarmee kreeg ik bij simpele programmaatjes met 2 for loops erin al rare fouten, zelfs bij programma's die ik letterlijk uit de antwoorden van mijn schoolboek van C heb overgenomen. Ik heb ook Borland C++ Builder 5.0 nogwat, maar ik heb weinig zin om dat te installeren omdat m'n harddisk er zo vol van raakt (5000 bestanden in totaal en 300+ MB geloof ik).
ik heb gewoon GCC gebruikt. je kan gcc onder windows ook gebruiken. ik gebruik nu mingw ( http://www.mingw.org ) , vind ik erg prettig werken...
host:~/speeltuin>gcc -o sorteer sorteer.c
host:~/speeltuin>./sorteer
before sort: sorTeerMijAuB
after sort: ABMTeeijorrsu
ik heb het ook even gecrosschecked met de borland C/CPP compiler. daar werkt ie ook prima.

[ Voor 5% gewijzigd door xoror op 08-01-2003 00:32 ]

Mitsubishi Warmtepomp Uitlezen / Besturen | Optimaliseren


  • Aham brahmasmi
  • Registratie: Juni 2002
  • Laatst online: 21-12-2025
Nou, ik doe 't toch maar met een basis bubble sort. Misschien verbeter ik 'm nog iets om wat onnodige stappen over te slaan. Ik ben nu een PSD aan het maken en tegelijkertijd de code aan het aanpassen, want ik kan van een C programma wel uit mijn hoofd een PSD maken, maar niet met Assembler. Ik moet toch even zien wanneer de registers op stack moeten worden gezet en er weer van af gehaald, en wanneer precies gecontroleerd moet worden of het aantal malen dat een lus doorlopen moet worden bereikt is.

- In hoofdlijnen verdeelt het programma een string van 15 karakters (letters) in 14 paren die vergeleken worden. In de basis bubble sort worden alle string 14 keer gesorteerd, dwz de 14 paren worden 14 keer vergeleken. Dus: lus: 14x string sorteren > geneste lus: 14 paren sorteren. Een verbeterde bubble sort zou bij elke herhaling van het sorteren steeds 1 letterpaar minder vergelijken. De eerste keer dat de string gesorteerd wordt, worden dus alle paren vergeleken, en de laatste keer alleen het eerste paar.

- Ipv een index die je in C zou gebruiken, gebruik ik BX als karakterpointer om een letter uit een de string aan te wijzen. Bij elke letterpaar worden AH en AL vergeleken en in BX en BX+1 gezet. Als gewisseld moet worden in AH en AL BX+1 en BX gezet, en worden de letters dus omgewisseld.

Even een vraagje: betekent
code:
1
2
cmp al,ah
ja wissel
dat AH met AL vergeleken wordt, en ja (jump above) betekent dus dat AH hoger is dan AL? Dat zou betekenen dat als AH>AL, dan is de 1e letter hoger dan de 2e, en moeten ze dus verwisseld worden (bij "ja wissel" wordt subroutine 'wissel' aangeroepen).

[De rest komt hier zo, ik post dit alvast even]

Verwijderd

Ehm, waar ben je mee bezig als je je eigen code niet begrijpt? Dit is toch je eigen code die je toto nog toe had gemaakt? Anders zal je echt moeten beginnen met een PSD en daarna -daarvanuit- pas moeten gaan implementeren. Van alle talen is assembly zo'n beetje de laatste taal om in te gaan rotzooien tot het werkt.

En als Dev-C++ foutmeldingen geeft, dan doe je waarschijnlijk ook daadwerkelijk wat fout, dan helpt het waarschijnlijk niet om gcc (in de gedaante van "mingw") ook nog eens los te installeren, Dev-C++ gebruikt die compiler al. Als de error aangeeft dat dev-c++ "gcc" en/of "make" niet kan vinden, dan kan het probleem liggen aan de lange bestandsnamen in het pad, zoals bijv. bij "program files". En anders moet je hier op P&W eens rondkijken/topic openen over Dev-C++.

[ Voor 5% gewijzigd door Verwijderd op 10-01-2003 11:42 ]


  • Aham brahmasmi
  • Registratie: Juni 2002
  • Laatst online: 21-12-2025
Ik zei niet dat DevC++ foutmeldingen geeft, maar dat eenvoudige C programma's die horen te werken niet goed werken. Het compileren gaat dan goed (zonder errors), maar het programma geeft niet de juiste output (bijvoorbeeld bij 2 keer dezelfde lus doorlopen waarbij bij de tweede keer (o.a.) de indices van een array met lengte 5 alleen het cijfer 6 geprint wordt, terwijl de teller in de for loop weer op 0 wordt geïnitialiseerd). Het leek mij eigenlijk al sterk dat DevC++ niet goed zou werken, dus daaraan zal het wel niet liggen. Maar de fouten die ik maak moeten dan wel hele kleine dingetjes zijn, want het zijn echt hele eenvoudige programma's die ik schrijf. Ik post hier binnenkort misschien nog wat over.

Het mij is trouwens gelukt om een werkend sorteer/alfabetiseerprogramma te schrijven in Assembly!!
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
    .MODEL  small
    .STACK  100h
    .DATA
string  DB 'sorteermijnuaub'    ;De te sorteren string
    .CODE
    mov ax,@data    ;Laad het datasegment
    mov ds,ax       ; met de juiste waarde
    mov bx,0        ;Initialisatie karakterpointer
    mov cx,0        ; en teller

    call    sort        ;Roep subroutine sort aan

sort:   mov ah,[bx]     ;Laad de AH met karakterpointer BX (adres 1e letter)
    mov al,[bx+1]   ; en AL met BX+1 (adres 2e letter)
    cmp bx,0Eh      ;Controle of letters 14 en 14+1 al vergeleken zijn
    je  nxtsrt      ;Als alle letterparen zijn vergeleken, volgende lus
    cmp al,ah       ;Vergelijk de twee letters
    jb  wiss        ;Als 2e>1e, wisselen
                ;Als 2e=<1e, volgende 2 letters vergelijken

nxtkar: inc bx      ;Karakterpointer verhogen
    push    bx      ;Zet nieuwe stand karakterpointer op stack
    pop ax      ;Haal laatste waarde van AX van stack
    jmp sort        ;Verder met de geneste lus

wiss:   mov [bx],al     ;Laad AL in karakterpointer BX,
                ; zet adres 2e letter in 1e pointer
    mov [bx+1],ah   ;Laad AH in karakterpointer BX+1,
                ; zet adres 1e letter in 2e pointer
    push    ax      ;Zet register op stack (bewaar nieuwe volgorde)
    jmp nxtkar      ;Volgende 2 letters vergelijken

nxtsrt: inc cx      ;Teller verhogen
    cmp cx,0Eh      ;Van de 15 letters worden 14 (Eh) paren vergeleken
                ;de lus wordt ook 14x gesorteerd
    je  exit        ;De laatste keer dat verg aangeroepen wordt, exit
    push    cx      ;Bewaar tellerstand
    pop ax      ;De registers worden hersteld
    mov bx,0        ;Zet karakterpointer BX op 0 (eerste letterpaar)
    jmp sort        ;

exit:   mov ah,4Ch      ;Terug
    int 21h     ; naar DOS

    end         ;Einde programma

Het commentaar klopt op sommige plaatsen waarschijnlijk niet helemaal. Ik had wat probleempjes met de wisselprocedure, die ik nu nog steeds niet 100% begrijp maar dus wel werkend heb gekregen. Al met al heb ik toch kunnen laten zien aan mijn docent dat ik genoeg van Assembly begrijp, en ik heb een 8 gekregen. :)

[ Voor 7% gewijzigd door Aham brahmasmi op 10-01-2003 23:11 ]


Verwijderd

Heb je al wel meer in assembly geschreven? Want deze combi gaat fout/doet niks:
GAS:
1
2
    push    bx      ;Zet nieuwe stand karakterpointer op stack
    pop ax      ;Haal laatste waarde van AX van stack


Misschien moet je eens goed beargumenteren waar deze code voor dient (vooral voor jezelf)...

(En die fouten die jij krijgt met Dev-C++ zullen echt niet aan gcc (de compiler die Dev-C++ aanstuurt) liggen, die is enorm robuust, de linux-kernel wordt er nota bene mee gecompileerd)

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 24-08 23:08
Verwijderd schreef op 13 januari 2003 @ 09:45:
Heb je al wel meer in assembly geschreven? Want deze combi gaat fout/doet niks:
GAS:
1
2
    push    bx      ;Zet nieuwe stand karakterpointer op stack
    pop ax      ;Haal laatste waarde van AX van stack
Nou ja, dat is een primitieve manier om aan ax de waarde van bx toe te kennen. (Wat niet zo nuttig is, als het eerstvolgende wat je doet, ah en al vullen met gegevens uit het geheugen is).

Ik vind de ongebalanceerde push/pop instructies zorgelijker. Elke keer dat je langs het 'wiss' label komt, verhoog je de stack permanent met een byte. Langzaam maar zeker gebruik je zo dus je stack op. Niet zo netjes!

Sort als subroutine aanroepen (met 'call') slaat ook nergens op, als je die subroutine nooit verlaat (maar bruutweg het hele programma afsluit als je klaar bent). En als je toch een subroutine maakt, zorg dan ook dat die z'n invoer uit op de stack geplaatste argumenten haalt. Nu 'ie z'n gegevens op een vaste plek heeft staan, kan 'ie nooit concurrent of recursief aangeroepen worden. Dat is misschien ook te veel gevraagd nu, maar maak er dan ook geen subroutine van (maw: laat dat hele 'call sort' statement weg).

Al met al een klein wonder dat de code werkt. :)

[ Voor 37% gewijzigd door Soultaker op 13-01-2003 10:03 ]


Verwijderd

Soultaker schreef op 13 januari 2003 @ 09:58:
Nou ja, dat is een primitieve manier om aan ax de waarde van bx toe te kennen. (Wat niet zo nuttig is, als het eerstvolgende wat je doet, ah en al vullen met gegevens uit het geheugen is).
Dat bedoel ik dus... ax vullen met bx, en dan al/ah weer vullen, tegenover het commentaar bij de instructies :? Die ongebalanceerde stack had ik nog niet eens zo snel gezien, dit was het eerste wat al opviel... Maar wat dacht je dan van het feit dat er nog steeds maar vanuit wordt gegaan dat het stringetje op adres 0 begint...
Sort als subroutine aanroepen (met 'call') slaat ook nergens op, als je die subroutine nooit verlaat (maar bruutweg het hele programma afsluit als je klaar bent). En als je toch een subroutine maakt, zorg dan ook dat die z'n invoer uit op de stack geplaatste argumenten haalt.
Je zou het een aangepaste "regparm" functie (zoals __fastcall in BC++/VC++) kunnen noemen, die dus de twee args in ebx en eax zet. ;)

Maar over het algemeen is het argument om assembly te gebruiken, gebaseerd op snelheidswinst, ik denk dat een C-compiler het echt wel veeel beter kan dan dit... Idd door die call weg te laten, door de blokken beter te ordenen en de overbodige push/pop's weg te halen, kan het echt wel veel beter (en fatsoenlijker). Me handen jeuken, maar ik ga niet (meer) iemands huiswerk doen...

[ Voor 4% gewijzigd door Verwijderd op 13-01-2003 10:36 ]


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 24-08 23:08
Verwijderd schreef op 13 January 2003 @ 10:35:
Je zou het een aangepaste "regparm" functie (zoals __fastcall in BC++/VC++) kunnen noemen, die dus de twee args in ebx en eax zet. ;)
Ach ja, hij vult bx met een character pointer enzo; dat had ik even over 't hoofd gezien. Blijft het punt dat een functie hoort te retourneren (en niet de applicatie af moet sluiten) natuurlijk.
Maar over het algemeen is het argument om assembly te gebruiken, gebaseerd op snelheidswinst, ik denk dat een C-compiler het echt wel veeel beter kan dan dit... Idd door die call weg te laten, door de blokken beter te ordenen en de overbodige push/pop's weg te halen, kan het echt wel veel beter (en fatsoenlijker). Me handen jeuken, maar ik ga niet (meer) iemands huiswerk doen...
Het kan zeker beter. Het zou me al verbazen als deze oplossing 100% correct is. Dat een C compiler het beter doet, qua efficientie, is nog maar de vraag, bij gebrek aan low-level constructies die zo handig zijn bij sorteren (swappen via de stack enzo).

  • Aham brahmasmi
  • Registratie: Juni 2002
  • Laatst online: 21-12-2025
Tuurlijk kan het beter. Ik heb mij ook vergist bij het gebruiken van push/pop bij de registers. Ik had nog niet goed door hoe het precies werkte, maar ik moet ook zeggen dat het studiemateriaal wat ik heb nogal beroerd is. Het dus meer geluk dan wijsheid dat het programma werkt.
Ik weet ook dat ik het aanroepen van subroutines (met call) niet erg netjes heb afgehandeld; ik zat gewoon nogal te worstelen met de volgorde van de instructies (de layout van het programma), en het kwam zo uit dat ik nergens meer een ret gebruikte. Daar heb ik nog wel wat aandacht aan besteed in een volgende versie van het programma die ook een verbeterde bubble sort bevatte, maar dat werkte nog niet goed vanwege mijn verkeerde gebruik van push en pop.

Je/jullie moet(en) ook niet vergeten dat ik in anderhalve week door af en toe wat te zoeken op inet en in een (niet erg goed geschreven) dictaat microcomputertechniek genoeg kennis op moest doen om de opdracht te kunnen maken. Het ging er om dat voor de docent ik kon aantonen dat ik begreep hoe programmeren in Assembly in grote lijnen werkt, en dat ik een werkend programma kon maken. Dat is uiteindelijk gelukt.
Bovendien wordt in Assembly programmeren in afnemende mate belangrijk in het vakgebied waar mijn studie op is gericht (technische natuurkunde), aangezien tegenwoordig steeds meer meet- en regelelektronica met microcontrollers in hogere programmeertalen zoals C geprogrammeerd kan worden.

Verwijderd

Soultaker schreef op 13 January 2003 @ 10:40:
Ach ja, hij vult bx met een character pointer enzo; dat had ik even over 't hoofd gezien. Blijft het punt dat een functie hoort te retourneren (en niet de applicatie af moet sluiten) natuurlijk.
Als je een functie inline-d in C gebeurt dit ook hoor... Scheelt weer aan stackoperaties. :)
Het kan zeker beter. Het zou me al verbazen als deze oplossing 100% correct is. Dat een C compiler het beter doet, qua efficientie, is nog maar de vraag, bij gebrek aan low-level constructies die zo handig zijn bij sorteren (swappen via de stack enzo).
Absoluut dat een C compiler dit beter kan dan de TS tot nog toe... En die swap gebeurt in gcc door middel van (gnu assembly):
GAS:
1
2
3
4
5
6
7
    movb    (%edx), %cl
    movb    1(%edx), %al
    cmpb    %al, %cl
    jle .L24
    movb    %al, (%edx)
    movb    %cl, 1(%edx)
.L24:   inc edx
Dat is bijna letterlijk wat ik zou doen, in elk geval even snel.

De functie is vrij goed vanuit gcc (immers elke optimalisatie-algoritme dat je zelf gebruikt kun je ook in een compiler inbouwen). Het kan echter altijd korter. Mijn huidige versie (zelfde een-directionele sort als de TS:
GAS:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
sort:
    pushl   %ebx
    movl    12(%esp), %ebx
    decl    %ebx
    je  .L27
.L17:
    movl    8(%esp), %edx
    movl    %ebx, %ecx
.L25:
    movb    (%edx), %ah
    movb    1(%edx), %al
    cmpb    %al, %ah
    jle .L24
    movb    %al, (%edx)
    movb    %ah, 1(%edx)
.L24:
    incl    %edx
    decl    %ecx
    jne .L25
    decl    %ebx
    jne .L17
.L27:
    popl    %ebx
    ret

(Is zowel in gnu (at&t) assembly als in 32bits assembly, omdat ik niet alles voor wil kauwen. eax,ecx en edx zijn de enige "clobber" registers van gcc, vandaar deze keuze)

Ik weet eigenlijk zo 1..2..3 niet of je ook een "jle" kunt doen, vanuit een "decl", gcc durft dit niet in elk geval...
Pagina: 1