反转字符串 - NASM x86汇编代码

时间:2015-02-15 11:17:14

标签: assembly x86 segmentation-fault nasm machine-language

我正在尝试在NASM中编写一个代码来反转一个字符串,但我不断遇到seg错误。我找到了一些问类似的问题,但回复并没有帮助我。

下面是代码:

    %include "asm_io.inc"

    segment .data

    prompt1         db      `Enter String: `,0
    prompt2         db      "Reverse: ",0

    segment .bss

    stringlabel     resd    100

    segment .text

    global reverse
    extern printf
    extern scanf

    reverse:

    call    readstring
    call    strlen
    mov     eax, 5
    mov     ebx, stringlabel        ;save first address of the string
                                    ;eax contains the string length
    add     eax, ebx                ;last address of the string
    sub     eax, 1                  ;account for null character

    whileReverse:

    mov     ecx, [eax]              ;save value of last marker into a temp register
    mov     edx, [ebx]              ;save value of first marker into a temp register
    mov     [ebx], ecx              ;save value in ecx to the memory location pointed by ecx
    mov     [eax], edx              ;save value in edx to the memory location pointed by eax
    inc     ebx                     ;increment first marker, i.e,move closer to the centre
    dec     eax                     ;decrement last marker
    cmp     eax, ebx                ;if first marker is larger then the second marker, then swapping is done
    ja      whileReverse

    whileReverseEnd:

    popa
    leave
    ret


    readstring:

    enter   0,0                     ;setup routine
    pusha                           ;push all registers
    mov     eax, prompt1            ;move user input (String) into the register
    call    print_string            ;print prompt  on terminal


    ;READ A BYTE FROM STDIN
    ;this sub-block of code is to read the user input
    ;I found it on the NASM wikibooks site
    ;I have an idea of what may be going on
    ;But I am not sure why all these registers
    ;are being used

    mov     eax, 3                  ;read
    mov     ebx, 0                  ;read from standard input
    mov     ecx, stringlabel        ;address to pass
    mov     edx, 100                ;input length
                                    ;must save the input string
                                    ;in eax (requirement)
    int     0x80                    ;call the kernal
    call    print_string            ;print user input on terminal
    popa
    ret

    strlen:

    enter   0,0
    pusha

    mov     eax, prompt1            ;save the address of the first memory 'block' of stringlabel in eax
    mov     ebx, eax                ;move both markers to the first memory 'block' address

    whileLen:

    mov     cl, [eax]               ;move value from eax to lower ecx
    cmp     cl, 0                   ;look for null value in the current address
    je      whileLenEnd             ;exit loop if null value is found in the current address
    inc     eax                     ;else, increment eax to move on to the next memory location or 'block'
    jmp     whileLen                ;jump back to while loop and repeat

    whileLenEnd:

    sb      eax, ebx                ;subtract the final positions of the markers to calculate the string length must save the string length in eax {requirement)
    pop     ebx
    pop     ecx
    leave
    ret

2 个答案:

答案 0 :(得分:1)

将5分配给EAX会破坏调用strlen的目的。只需删除它。

call    strlen
mov     eax, 5

以下行的评论是错误的。将EAX放在字符串的最后一个字符上需要减量。

sub     eax, 1                  ;account for null character

您需要将字符视为字节而不是dwords。

mov     cl, [eax]  ;save value of last marker into a temp register
mov     dl, [ebx]  ;save value of first marker into a temp register
mov     [ebx], cl  ;save value in ecx to the memory location pointed by ecx
mov     [eax], dl  ;save value in edx to the memory location pointed by eax

此代码无法正确退出程序。调用核心的EXIT函数。

whileReverseEnd:

popa
leave
ret

由于 readstring 使用enter 0,0,您需要在leavepopa之间添加匹配的ret

strlen 中,不使用pusha会更容易。那样EAX可以退货!

strlen:
enter   0,0
push    ecx
push    ebx
mov     eax, prompt1  ; <-- Change this to    stringlabel

下一行可能有拼写错误。将 sb 更改为sub

sb      eax, ebx                ;subtract the final positions 

答案 1 :(得分:-1)

;***************************************************
;
; Reversing a string in 8086 ALP
;
; code by Akshay Rajput
;****************************************************

section .data
msg db "microprocessor"
len: equ $-msg

section .bss
rstring resb 14

section .code 
global _start

_start:
    %macro write 2
    mov eax,4
    mov ebx,1
    mov ecx,%1
    mov edx,%2
    int 80h
    %endmacro

    %macro read 2
    mov eax,3
    mov ebx,0
    mov ecx,%1
    mov edx,%2
    int 80h
    %endmacro

    mov esi,msg
    mov ecx,14
    add esi,len-1
    mov edi,rstring

AGAIN:mov eax,[esi]
    mov [edi],eax
    dec esi
    inc edi
    LOOP AGAIN

    write rstring,14



    mov eax,1
    int 80h