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