2015-02-11 52 views
0

無法取得此字符串的字符順序,它可以使用整數而不是字符串。它正在輸出包括字符串在內的所有內容,直到我「反轉」它。然後它只輸出一個空行......而不是以相反的順序輸出字符串。我認爲我的字符串數組發生了一些事情。任何幫助將不勝感激...ASM(NASM)中的字符串的逆向排列順序

更新:我得到它的工作,但不得不手動從array2Len減去1(當然將其放置在EAX等)。這沒有任何意義,爲什麼array2Len一個?

我用:

array2Len: equ $-array2 in the .data section 

但它說,這是14的長度(當我測試時輸出的話),而實際上它是13 ...你會在底部看到我手動使它工作,(它現在被註釋掉)。任何人都知道爲什麼Equ $ -array2會被一個關掉?

extern printf   ; the C function, to be called 

SECTION .data    ; Data section, initialized variables 
unitSize: dd 4       ; size of unit (for testing starts at 4) 
array: dd 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 ; this is a test array for testing purposes 
array2: db "Hello, world!", 0    ; second array test for if it is a string 
array2Len: equ $-array2 
arrayLen: dd 10       ; length of array 
;ainput: db "%d", 0      ; input format 
asoutput: db "%s", 0 
aoutput: db "%d ", 0     ; output format 
newline: db "", 10, 0     ; format for a new line 
SECTION .bss        ; BSS, uninitialized variables 

SECTION .text    ; Code section. 

global main    ; the standard gcc entry point 

reverse: 
    ;lets test 
    push ebp 
    mov ebp, esp 

    mov ebx, [ebp+8] 
    mov eax, [ebp+12] 
    mov ecx, [ebp+16] 
    sub esp, 8 

    mov dword [ebp-4], eax     ; size of units. i.e. is it 4 bytes? 1 byte between array values (such as a string), or 4 bytes (like an int, etc.) 
    mov dword [ebp-8], ecx     ; size of array (including if it is strings) 
    push ebx 
    mov esi, ebx       ; array index that starts at beginning of array 
    mov edi, ebx       ; array index that will start at end of array 

    ; calculate the end of the array by multiplying the (length of array - 1) by unit size 
    mov eax, [ebp-8] 
    sub eax, 1 
    mov ebx, [ebp-4]      ; size of units 
    mul ebx 
    add edi, eax       ; array index now starts at the end of the array 

    ; going to go through until we get to the middle 
    mov ebx, 2 
    mov eax, [ebp-8] 
    cdq 
    div ebx 
    mov ecx, eax       ; number of times to run loop set up 
    ;mov ecx, 8 

    ;jmp .stringloop 
    mov eax, 4 
    cmp [ebp-4], eax 
    jne .stringloop 

.loop:          ; loop through indexes of array and reverse the array 

    push dword [esi] 
    push dword [edi] 
    pop dword [esi] 
    pop dword [edi] 

    add esi, [ebp-4] 
    sub edi, [ebp-4] 

    loop .loop 
    jmp .end 
.stringloop: 
    mov al, [esi] 
    mov bl, [edi] 
    mov [esi], bl 
    mov [edi], al 

    ;inc esi 
    ;dec edi 
    add esi, 1;[ebp-4] 
    sub edi, 1;[ebp-4] 

    loop .stringloop 
.end: 
    pop ebx         ; get back our address of the array 
    mov esp, ebp       ; takedown stack frame 
    pop ebp         ; same as "leave" op 

    mov eax, ebx       ; put the address of the array in eax to get it back 
    ret          ; return :) 

main:     ; the program label for the entry point 
    push ebp   ; set up stack frame 
    mov  ebp,esp 

    ;jmp .stringcheck 
    mov ecx, [arrayLen] ; loop counter set up 
    mov esi, 0  ; counter to increment set up for looping through array 
.loop: 

    push ecx         ; make sure to put ecx (counter) on stack so we don't lose it when calling printf) 
    push dword [array + esi]     ; put the value of the array at this (esi) index on the stack to be used by printf 
    push dword aoutput       ; put the array output format on the stack for printf to use 
    call printf         ; call the printf command 
    add esp, 8         ; add 4 bytes * 2 
    pop ecx          ; get ecx back 

    add esi, 4 
    loop .loop 

    push dword newline 
    call printf 
    add esp, 4 

    mov eax, [arrayLen] 
    push eax 
    mov eax, array 
    mov ecx, [unitSize] 
    push ecx 
    push eax 
    call reverse 

    mov ebx, eax        ; got address of array back from reverse function 
    mov ecx, [arrayLen]       ; counter for # of times loop to run set up 
    mov esi, 0         ; index counter set up 
.loop2: 
    push ebx 
    push ecx         ; make sure to put ecx (counter) on stack so we don't lose it when calling printf) 
    push dword [ebx + esi]     ; put the value of the array at this (esi) index on the stack to be used by printf 
    push dword aoutput       ; put the array output format on the stack for printf to use 
    call printf         ; call the printf command 
    add esp, 8         ; add 4 bytes * 2 
    pop ecx          ; get ecx back 
    pop ebx 

    add esi, 4 
    loop .loop2 

    push dword newline 
    call printf 
    add esp, 4 

.stringcheck: 
    push dword array2       
    push dword asoutput       ; string output format 
    call printf         ; call the printf command 
    add esp, 8         ; add 4 bytes * 2 

    push dword newline 
    call printf 
    add esp, 4 

    ;mov eax, array2Len 
    ;sub eax, 1 
    ;mov ebx, eax 
    mov ebx, array2Len 
    push ebx 
    mov eax, array2 
    mov ecx, 1 
    push ecx 
    push eax 
    call reverse 

    mov ebx, eax 

    push ebx 
    push dword asoutput 
    call printf 
    add esp, 8 

    push dword newline 
    call printf 
    add esp, 4 

    mov  esp, ebp ; takedown stack frame 
    pop  ebp   ; same as "leave" op 

    mov  eax,0  ; normal, no error, return value 
    ret     ; return 
+0

看一看[這裏](http://stackoverflow.com/questions/28447178/two-program-functions-to-be-created-in-asm-nasm-that-deals-with-arrays/28449790# 28449790),看看你是否有幫助 – 2015-02-12 02:45:39

回答

2

該字符串被定義爲13個字節,但它是明確地「空」終止 - 在作爲一個標記,以指示所述字符串的末尾結束一個零字節,見here

這是你如何定義它

array2: db "Hello, world!", 0    ; second array test for if it is a string 
array2Len: equ $-array2 

db指令說你是定義字節,13個字節給出一個字符串,則空字節的逗號後明確給出。當計算array2Len時,您告訴彙編程序評估表達式$-array2,符號$是當前偏移量,它是字符串文字結尾之後的一個偏移量(因爲空字節)。

+0

哦,我明白了。所以當處理字符串/數據庫時,它總是會關閉一個?還是有一些命令或某些東西使它像我一樣使用時不會被一個人忽略?還是不是要像我那樣使用? **更新:剛剛計算出我可以這樣做:array2Len:equ $ -array2-1 ** – Rex 2015-02-12 04:00:20

+1

使用空字節標記字符串的末尾只是一個約定,但您可以跟蹤字符串長度在你的程序的內部(像有一個像你這樣的變量,array2Len,其中包含的長度)。但是,您可以調用'printf',它要求字符串以null結尾。在你的變量中,你可以設置長度爲'$ -array2-1',這將減去1個字節的空終止。 – amdn 2015-02-12 04:04:38

+0

謝謝!現在很好用! :) – Rex 2015-02-12 04:05:36

相關問題