在ASM(NASM)中反转字符串的顺序

时间:2015-02-11 23:31:15

标签: assembly x86 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

1 个答案:

答案 0 :(得分:2)

该字符串定义为13个字节,但它显式为“null”终止 - 最后一个零字节用作表示字符串结尾的标记,请参阅here

这就是你定义它的方式

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

db指令表示您正在定义字节,13个字节作为字符串文字给出,空字节在逗号后显式给出。当您计算array2Len时,您告诉汇编程序计算表达式$-array2,符号$是当前偏移量,它是字符串文字结尾之后的一个(因为空字节)。 / p>