2016-06-25 33 views
0

Ich habe einige Assembler-Code auf einen Zähler, um die Länge einer Zeichenfolge zu zählen.Assembly AT & T - Negative Flag & Loop + String Inhalt holen

Die Zeichenfolge ist -123.

Ich habe nur die eine Frage:

  • Meine negative Kontrolle (cmp %r15, %r14/je Negative_counter) umgangen wird, auch wenn ich

  .data 
S:   .string "123" 
Result:  .quad 

      .text 
      .globl main 

main: 
    mov  $S,%rdx    #Storage of string 
    mov  $S,%rbx 
    mov  Result, %rax  #Location of result storage 

    mov  $10, %r8 


    mov  $1, %r11   #-1 counter creation with 2s complement 
    not  %r11    #negation of 1 
    add  $1, %r11   #2's complement complete 

    mov  $1, %r12   #-1 counter creation with 2s complement 
    not  %r12    #negation of 1 
    add  $1, %r12   #2's complement complete, -1 established 


#R[rbx] is used here. 
Loop1:       #loop string from end to beginning 
    cmp  $0, (%rbx)   #compare base addresss value with null 
    je  Counter_Made  #if null, branch to end loop. 
    add  $1, %r11   #increment %r11 by 1 for each digit thats not null (creates counter for 2nd loop) 
    add  $1, %rbx   #Next string digit 
    jmp  Loop1    #reinitiate loop 

#Counter of string made -149, would given counter value of 3 

#R[rdx] and r14 is used here. 
Counter_Made: 
    cmp  $0,%r11    #check if %r11 is zero 
    je  Output    #End program, output null result 

    mov  $S, %r14   #move into register 14 
    sub  $7, %r14   #Shift to least significant bit 

    mov  $13, %r15 
    and  $15, %r15 


    cmp  %r15, %r14   #Determine negativity/positivity of integer, if <0 value is negative 
    je  Negative_counter 
    jmp  Positive_loop 

Positive_loop: 
    cmp  %r12,%r11   #End of loop check 
    je  Output    #Store result if loop end condition satisfied 

    mov  (%rdx), %r10  #grab first byte in address string 
    sub  $30,(%rdx)   #Conversion from 8bitASCII to 2Bit Binary 
    and  $15, %r10   #initialize size to match 

Positive_inner_loop: 
    mov  %r11, %r9 
    cmp  $0, %r9    #Compare loop length with 0 to see if it needs multiplication 
    je  InnerLoopDone  #Jump to inner loop done once length = 0 
    imul %r8, %r10   #Place holder multiplication 


InnerLoopDone: 
    add  %r10,%rax 
    sub  $1, %r11   #Decrease Length to grab next ten multiplication place holder position 
    mov  1(%rdx), %rdx   #next digit position 
    jmp  Positive_loop 



Negative_counter: 
    add  $1,%rdx 
    jmp  Negative_loop 

Negative_loop: 
    cmp  %r12,%r11 
    je  Negative_Complement 
    jmp  Negative_loop 

Negative_Complement: 
    not  %rdx    #Convert to 2's complement with negation and then + 1 
    add  %r14,%rdx 
    jmp  Output 

Output: 
    ret 
+0

Beachten Sie, dass Ihre Frage besagt, dass die Zeichenfolge "-123" ist, aber Ihr Code "123" (ohne Minuszeichen) verwendet. Das ist jedoch nicht das Problem. –

+0

Duplikate von welchen Ihrer vorherigen Fragen? Ich kopiere meine Antwort dort und lösche sie hier. (Danach können Sie Ihre eigene Frage löschen). Eine andere Möglichkeit besteht darin, die vorherige Frage zu löschen oder sie einfach als ein Duplikat zu markieren. –

+1

Wenn Sie dem Rat von Petrus folgen und die alte Frage entweder als Duplikat von diesem oder diesem als Duplikat des alten schließen wollen, ist das in Ordnung. Einfach den Link zu der anderen Frage posten. Aber Sie können den Text dieser Frage absolut nicht ausradieren, wenn Sie sich Mühe geben, ihn zu beantworten. –

Antwort

1

eine negative ganze Zahl habe Ich denke du redest über diesen Code-Block. Ich habe es mit weniger nutzlosen Kommentaren neu kommentiert. z.B. move into register 14 sagt Ihnen nichts, was Sie nicht von der mov $S, %r14 Anweisung selbst erzählen können. Kommentare sollten erklären, was im Algorithmus vor sich geht. Angenommen, die Person, die die Kommentare liest, hat eine Kopie des Handbuchs mit den Anweisungen verfügbar, also geben Sie nur einen Kommentar zu den mechanischen Details ab, wenn Sie etwas Nicht-Offensichtliches tun. (Wie mit einer Flagge, die noch vor ein paar Anweisungen gesetzt wurde).

mov  $S, %r14   # r14 = pointer to the start of the string 
    sub  $7, %r14   # r14 = pointer to 7 bytes before the beginning of the string 

    mov  $13, %r15 
    and  $15, %r15   # r15 = 13 & 0xF = 13 


    cmp  %r15, %r14   # 
    je  Negative_counter # jump if (S-7) == 13 

    # jmp  Positive_loop  # this is totally redundant, you don't need a jmp to jump over the blank line before the next block of code. 

Positive_loop: 

Klar S-7 (das heißt &S[-7] in C-Syntax) wird nie gehen 13 bis gleich, weil Adressen der Dinge in der .data oder .rodata Abschnitt werden nie nahe 0 auf Linux sein.


Sie leicht diese mit einem Debugger gesehen haben könnten, durch einen Haltepunkt oder Einzelschritteinstellung, bis Sie auf dem Inhalt dieses regs auf die cmp/je und suchen bekamen.

Siehe die Unterseite der Tag Wiki für eine schnelle Erklärung der Putting gdb in layout reg Modus, wo es zeigt die Register-Werte, wie Sie Single-Step.


Es gibt wahrscheinlich viele andere Dinge falsch mit Ihrem Code auch, aber es ist lange und ich habe es nicht gelesen alle.

+0

Der ursprüngliche Kommentar zu 'sub $ 7,% r14' ist" shift to least significant bit ". Ich bin verblüfft, warum das OP meint, dass sich dadurch etwas verschiebt. Obwohl ... dies könnte eine Art von Missverständnis von Adressen sein, unter der Annahme, dass bei Index -7 das niedrigstwertige Byte der Adresse von S gefunden werden kann (vorausgesetzt, S zeigt auf das höchstwertige Byte) und das ist irgendwie das erste Byte . Scheint wie ein komplettes Missverständnis von Adressen und Strings. –