0 Daumen
419 Aufrufe

Hallo,

Ich bin ein absoluter Neuling in Assembler und versuche die folgende Aufgabe zu verstehen:

Übersetzen Sie die beiden folgenden C-artigen Programmausschnitte in NASM-artige Pseudocodes:

collatz ( n ) {
    k = 0;
  while ( n > 1) {
        if ( n % 2 == 0) { // n is even
            n = n / 2;
        } else { // n i odd
            n = n * 3;
            n = n + 1;
        }
        k = k + 1;
     }
    return k ;
}


Nun die Lösung und wie ich versuch habe es zu verstehen:

global collatz

collatz:
mov rax , 0
mov r9 , 0 ; k = 0
; wie ich verstehe werden rax und r9 gleich 0 gesetzt, warum?

while: ; While Condtion ist in collatz:
cmp rdi , 1
jle end ; Benden der schleife wenn bedingung nicht mehr stimmt
; nun werden rdi und 1 miteinander verglichen, warum?

if:
mov rax , rdi ; kopiere rdi (n) in rax
mov rsi , 2 ; kopiere die 2 in rsi
div rsi ; teile rax/rdi

mod: ; ausfuehrung von mod bedingung
mov rax , rdi ; kopiere eingabe von rdi in rax
mov rsi , 2 ; kopiere die 2 in rsi
div rsi ; rax/ rsi
mov rdi , rax ; kopiere eingabe von rax in rdi
add r9, 1
jmp while

else: ; n= n *3 und n = n + 1
mov r10, rdi ; kopiere eingabe von rdi in r10
imul r10, 3 ; n = n * 3
add r10, 1 ; n = n + 1
mov rdi, r10 ; kopiere eingabe von rax in rdi
add r9 , 1 ; k = k + 1
jmp while

end:
mov rax , r9 ;
ret ; benden der funktion


Auf eine Beantwortung der Fragen und eine Schritt für Schritt Erklärung, warum es so gemacht wurde, würde ich mich sehr freuen.

Avatar von

1 Antwort

0 Daumen

Der erste C-artige Programmausschnitt ist eine Funktion namens "collatz", die eine ganze Zahl n als Argument nimmt. Die Funktion führt eine Schleife aus, solange n größer als 1 ist. Innerhalb der Schleife wird überprüft, ob n gerade oder ungerade ist. Wenn n gerade ist, wird es durch 2 geteilt. Wenn n ungerade ist, wird es mit 3 multipliziert und um 1 erhöht. In jeder Durchlauf der Schleife wird die Variable k um 1 erhöht. Am Ende der Funktion wird k zurückgegeben.

Eine mögliche Übersetzung des Programmausschnitts in NASM-artigen Pseudocode wäre:

collatz:
  push ebp           ; speichert den aktuellen Wert von EBP
  mov ebp, esp       ; setzt EBP auf den aktuellen Wert von ESP
  mov eax, [ebp+8]    ; kopiert den Wert von n in eax
  mov ecx, 0          ; setzt k auf 0
.loop:
  cmp eax, 1          ; vergleicht n mit 1
  jle .end           ; springt zu .end, wenn n <= 1
  test eax, 1        ; testet, ob n ungerade ist
  jz .even           ; springt zu .even, wenn n gerade ist
.odd:
  add eax, eax       ; erhöht eax um 1
  add eax, eax       ; multipliziert eax mit 3
  jmp .next         ; springt zu .next
.even:
  shr eax, 1          ; teilt eax durch 2
.next:
  inc ecx           ; erhöht k um 1
  jmp .loop         ; springt zu .loop
.end:
  mov eax, ecx       ; kopiert den Wert von k in eax
  pop ebp           ; stellt den ursprünglichen Wert von EBP wieder her
  ret               ; beendet die Funktion und gibt den Wert von eax zurück

Es ist wichtig darauf hinzuweisen, dass dies nur eine Möglichkeit der Übersetzung ist und dass es Unterschiede zwischen verschiedenen Assembler-Sprachen und -Systemen geben kann.

Avatar von

Ein anderes Problem?

Stell deine Frage

Willkommen bei der Stacklounge! Stell deine Frage einfach und kostenlos

x
Made by a lovely community