Bestimmung Minimum



  • warum kommt als minimalwert 0 raus?

    data_items: 
        .long   3, 2 ,34, 76, 0 
    
        # ----- text section ----- 
        .section .text 
        .globl _start 
    
    _start: 
        movl    $0, %edi 
        movl    data_items(, %edi, 4), %eax 
        movl    %eax, %ebx 
    
    start_loop: 
        cmpl    $0, %eax 
        je      loop_exit 
    
        incl    %edi 
        movl    data_items(, %edi, 4), %eax 
    
        cmpl    %ebx, %eax 
        jge     start_loop 
    
        movl    %eax, %ebx 
        jmp     start_loop 
    
    loop_exit: 
        movl    $1, %eax 
        int     $0x80
    


  • Ohne den Code zu analysieren, dürfte von 3, 2 ,34, 76, 0 wohl 0 der niedrigste Wert - also das Minimum - sein.



  • Der Wert 0 sollte mein Abbruchkriterium werden.
    Aufgrund dessen sollte 0, bezüglich der Berechnung, nicht mit
    einkalkuliert werden. Demnach müsste nun 2 der
    neue Minimalwert sein.



  • movl    %eax, %ebx 
        jmp     start_loop
    

    Hier mußt Du dafür sorgen, daß, wenn eax == 0 ist, eax nicht nach ebx geschoben wird.



  • Ich habe mir das mal Spaßes halber von C aus angeschaut:

    #include "stdio.h"
    typedef struct _myS
    {
      int v;
      int w;
      int x;
      int y;
      int z;
    }myS;
    
    int min(myS* S)
    {
        int retVal = *(int*)(S);
        int i = 1;
        while ((*(((int*)S)+i))!=0)
        {
            if ((*(((int*)S)+i))<retVal)
                retVal = *(((int*)S)+i);
            i++;
        }
        return retVal;
    }
    
    int max(myS* S)
    {
        int retVal = *(int*)(S);
        int i = 1;
        while ((*(((int*)S)+i))!=0)
        {
            if ((*(((int*)S)+i))>retVal)
                retVal = *(((int*)S)+i);
            i++;
        }
        return retVal;
    }
    
    int main()
    {
      myS S;
      S.v =  3;
      S.w =  2;
      S.x = 34;
      S.y = 76;
      S.z =  0;
      int minVal = min(&S);
      int maxVal = max(&S);
      printf("%i %i", minVal, maxVal);
      return 0;
    }
    

    Dies ergibt folgenden Objectcode mit -O1 und -march=i586:

    int min(myS* S)

    00401318	push   ebp
    00401319	mov    ebp,esp
    
    0040131B	mov    ecx,DWORD PTR [ebp+0x8]
    0040131E	mov    eax,DWORD PTR [ecx]
    00401320	mov    edx,DWORD PTR [ecx+0x4]
    00401323	test   edx,edx
    00401325	je     0x401337 <min+31>
    00401327	cmp    eax,edx
    00401329	jle    0x40132d <min+21>
    0040132B	mov    eax,edx
    0040132D	mov    edx,DWORD PTR [ecx+0x8]
    00401330	add    ecx,0x4
    00401333	test   edx,edx
    00401335	jne    0x401327 <min+15>
    
    00401337	pop    ebp
    00401338	ret
    

    int max(myS* S)

    00401339	push   ebp
    0040133A	mov    ebp,esp
    
    0040133C	mov    ecx,DWORD PTR [ebp+0x8]
    0040133F	mov    eax,DWORD PTR [ecx]
    00401341	mov    edx,DWORD PTR [ecx+0x4]
    00401344	test   edx,edx
    00401346	je     0x401358 <max+31>
    00401348	cmp    eax,edx
    0040134A	jge    0x40134e <max+21>
    0040134C	mov    eax,edx
    0040134E	mov    edx,DWORD PTR [ecx+0x8]
    00401351	add    ecx,0x4
    00401354	test   edx,edx
    00401356	jne    0x401348 <max+15>
    
    00401358	pop    ebp
    00401359	ret
    


  • hmpf schrieb:

    warum kommt als minimalwert 0 raus?

    Weil die letzte Zahl die du bearbeitest, die 0 ist.

    Beim nächsten Mal könntest du den code für die Mitleser besser auskommentieren, denn hättest du das gemacht, dann hättest auch du vermutlich eher selbst gesehen, wo dein Fehler ist.

    Diese Reihenfolge(Lesen, Bearbeiten, Testen) funktioniert nur, wenn man nach dem größten Wert sucht. Wenn du den kleinsten Wert suchst, dann musst du mit der abschließenden Null dem Registervergleich zuvorkommen.

    Also nochmal für die interessierten Mitleser:
    zum Schluss steht in ebx der kleinste Wert, also 2. Der vorletze Wert aus der aus dem Speicher gelesen wird ist 76. Dann wird vor dem nächsten Vergleich in der Schleife die 0 nach Eax geladen. Ebx=2 und Eax=0 werden verglichen. Ebx bekommt den kleinsten Wert, also Null. Dann wird geprüft, ob Eax=0 ist.

    Um diesem Problem aus dem Weg zu gehen, ist es praktischer, die Ausleserei an den Anfang der Schleife zu stellen, und erstmal schauen, ob schon Schluss ist. Und nicht erst schauen, ob schon Genug des guten ist, nachdem wir bereits die wichtigsten Mitarbeiter entlassen haben 😉

    ( in einem anderen Thread habe ich mal ein so ähliches Programm für Einsteiger geschrieben: http://www.c-plusplus.net/forum/viewtopic-var-t-is-275663-and-postdays-is-0-and-postorder-is-asc-and-start-is-10-and-sid-is-46c623e39dcaa88e3e6b4105af9a5866.html )



  • Vielen Dank für eure super Erklärungen,
    jetzt habe ich es auch verstanden 😃


Anmelden zum Antworten