2017-05-08 44 views
10

我想要使用鏈接列表程序,它將顯示用戶輸入的反向字符串。以下是我的程序來反轉用戶輸入的字符串。這也給字符串的長度:結合LinkedList和字符串反轉作爲目標是要了解LinkedList

TITLE ReadStringProc (ReadStringProc.asm) 

include irvine32.inc 

ListNode STRUCT 
    NodeData DWORD ? 
    NextPtr DWORD ? 
ListNode ENDS 

NULL = 0 
Counter = 0 

.data 
input    byte  100 dup(0)       
stringinput   byte  "Enter any string: ",0   
totallength   byte  "The total length is: ",0 
reverse    byte  "The reverse string is: ",0 

LinkedList LABEL DWORD 
REPT input 
    Counter = Counter + 1 
    ListNode <Counter, ($ + Counter * SIZEOF ListNode)> 
ENDM 
ListNode <0,0> ; tail node 




.code 




stringLength  proc 
        push  ebp 
        mov   ebp, esp 
        push  ebx 
        push  ecx 
        mov   eax, 0 
        mov   ebx, [ebp+8] 
L1: 
        mov   ecx, [ebx] ;you can use ecx, cx, ch, cl 
        cmp   ecx, 0  ;you can use ecx, cx, ch, cl 
        JE   L2 
        add   ebx, 1 
        add   eax, 1 
        jmp   L1 
L2: 
        pop   ecx 
        pop   ebx 
        mov   ebp, esp 
        pop   ebp 
        ret   4 

stringLength  endp 

swap MACRO   first,last 
        push  eax 
        mov   ah, first 
        mov   al, last 
        xor   al, ah ;x 
        xor   ah, al ;y 
        xor   al, ah ;x 
        mov   last, al 
        mov   first, ah 
        pop   eax 
endM 

stringReverse proc 
        push  ebp 
        mov   ebp, esp 
        push  OFFSET input 
        call  stringLength 
        mov   edx, [ebp+8] ;edx = offset string to reverse 
        mov   esi, offset 0 
        dec   eax  
        mov   ebx,edx  ;ebx stores the pointer to the first character 
        add   ebx,eax  ;now ebx store the pointer to the last character before the '$' 
        reverseloop: 
        push  edx 
        push  ebx 
        swap  [edx], [ebx] 
        inc   edx   ;increment of the right-most pointer 
        dec   ebx   ;decrement of the right-most pointer 
        cmp   edx, ebx  ;compares the left-most pointer to the right-most 
        jb   reverseloop 
jmp stopEnd  ;"ja", there is no need to check a condition twice 

stopEnd: 
        mov   esp, ebp 
        pop   ebp 
ret 4 

stringReverse  endp 

main proc 

        call  clrscr    
        mov   edx, offset stringinput  
        call  writeString 
        mov   edx, offset input 
        call  writeString  
        call  stringLength 
        mov   edx, offset input 
        mov   ecx, sizeof input 
        call  readstring   
        call  crlf 
        mov   edx,offset totallength 
        call  writestring 
        call  writedec  
        call  crlf 
        mov   edx, offset reverse 
        call  crlf 
        call  writeString 
        push  offset input 
        call  stringReverse 
        mov   edx, offset input 
        call  writeString  
        call  crlf 

        exit 
main    endp 


        end   main 

什麼我的目標是找到一種方法,使用這段代碼在硤歐文議會86本書中,並與我有這樣我可以使用的代碼結合起來鏈接列表顯示反向字符串:

ListNode STRUCT 
    NodeData DWORD ? 
    NextPtr DWORD ? 
ListNode ENDS 

TotalNodeCount = 15 
NULL = 0 
Counter = 0 

.data 
LinkedList LABEL DWORD 
REPT TotalNodeCount 
    Counter = Counter + 1 
    ListNode <Counter, ($ + Counter * SIZEOF ListNode)> 
ENDM 
ListNode <0,0> ; tail node 

.code 
main PROC 
    mov esi,OFFSET LinkedList 

; Display the integers in the NodeData members. 
NextNode: 
    ; Check for the tail node. 
    mov eax,(ListNode PTR [esi]).NextPtr 
    cmp eax,NULL 
    je quit 

    ; Display the node data. 
    mov eax,(ListNode PTR [esi]).NodeData 
    call WriteDec 
    call Crlf 

    ; Get pointer to next node. 
    mov esi,(ListNode PTR [esi]).NextPtr 
    jmp NextNode 

quit: 
    exit 

有人可以引導我到正確的路徑。謝謝。

+1

提示:您不需要使用那種過於複雜的XOR交換...您可以只將交換的寄存器寫出來。至於你的問題,不知道你爲什麼要使用鏈表,我不知道你卡在哪裏。雙向鏈表可能是有意義的,那麼你可以遍歷反向和向前,所以你不需要實際上扭轉字符串。 – Jester

+0

我在這裏的目標是重新打印鏈接列表格式中的反轉字符串。這是我的目標/優秀。謝謝您的幫助! –

+1

我希望能夠看到彙編中的鏈接列表。我的願望是用鏈表打印出一串像「hello world」這樣的字母,這樣我就能理解它在裝配中的工作原理。它不必使用反轉字符串。只需使用鏈接列表打印一個字符串就沒有問題。我想看看它背後的機制。謝謝 –

回答

2

你做不是需要鏈表來反轉一個字符串。不,認真。

但是,如果你堅持......

stringReverse proc;  <-- Warning: EBX and ESI are not preserved! 
    push ebp; 
    mov ebp, esp; 
    mov ebx, [ebp + 8]; <-- EBX = target string pointer 
    push ebx; 
    call stringLength; <-- we trust that stringLength() preserves EBX 
; mov ebx, [ebp + 8]; <-- uncomment this if it actually does not 
    mov esi, ebx; 
    xor edx, edx; 
    add ebx, eax; 
    neg eax; 

    @fill: 
    mov cl, [ebx + eax]; 
    sub esp, 8;   <-- allocating a new linked list item on stack 
    mov [esp], cl;  <-- 1st DWORD/1st BYTE = current character 
    mov [esp + 4], edx; <-- 2nd DWORD = next item pointer 
    mov edx, esp;  <-- EDX = current item pointer 
    inc eax; 
    jne @fill; 

    @roll: 
    mov cl, [edx]; 
    mov [esi], cl; 
    inc esi; 
    mov edx, [edx + 4]; <-- next item, here we go! 
    test edx, edx;  <-- what if we are done? 
    jne @roll; 

    mov esp, ebp;   <-- discarding the allocated stack 
    pop ebp; 
    ret 4; 

這樣的事情。

它應該工作,但我還沒有真正測試過。