2016-06-25 43 views
0

我寫了一些彙編代碼,使一個計數器來計算字符串的長度。大會AT&T - 負面標誌&循環+字符串內容取

字符串是-123

我有隻是一個問題:

  • 我否定的檢查(cmp %r15, %r14/je Negative_counter)被繞過,即使我有一個負整數

  .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

請注意,你的問題說該字符串是'-123',但是你的代碼使用'123'(沒有減號)。但這不是問題。 –

+0

您之前的哪些問題存在重複?我會在那裏複製我的答案並在此刪除它。 (在此之後,您將能夠刪除自己的問題)。另一個選擇是刪除上一個問題,或者將其標記爲與此相同。 –

+1

如果你想遵循彼得的建議,並且把舊的問題作爲這個問題的一個副本,或者把這個問題作爲舊問題的一個副本來處理,那很好。只需發佈鏈接到其他問題。但是,考慮到有人試圖回答這個問題,你絕對不能抹殺這個問題的內容。 –

回答

1

我想你在談論這塊代碼。我用更少的無用評論重新評論它。例如move into register 14不會告訴你任何你無法從mov $S, %r14指令本身得知的東西。評論應該解釋算法中發生了什麼。假設閱讀評論的人擁有可用的指導參考手冊的副本,那麼只有在您做了一些不明顯的事情時纔對機械細節發表評論。 (就像使用一個仍然從幾個指令前設置的標誌)。

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: 

顯然S-7(即在C語法&S[-7])永遠不會爲等於13,由於在.data或.RODATA部東西地址永遠不會是接近0 Linux上。


你可以很容易地看到了這一個調試器,通過設置斷點或單步執行,直到你到了CMP/JE,看着那些REG的內容。

查看標記維基的底部,以便快速瞭解gdb進入layout reg模式,在這種模式下它將單步顯示寄存器值。


您的代碼可能還有很多其他的錯誤,但它很長,我沒有看完。

+0

對'sub $ 7,%r14'的原始評論是「轉移到最低有效位」。我非常驚訝爲什麼OP認爲這會改變任何事情。儘管......這可能是對地址的某種誤解,假設在索引-7處可以找到S的地址的最低有效字節(假設S指向最高有效字節)並且這是第一個字節,但是以某種方式。看起來像是對地址和字符串的完全誤解。 –