Переверните строку на месте - код сборки NASM x86

Я пытаюсь написать код в 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 ответа

Присвоение 5 EAX отменяет цель вызова strlen. Просто удали это.

call    strlen
mov     eax, 5

Комментарий в следующей строке неверен. Декремент необходим для размещения EAX на последнем символе строки.

sub     eax, 1                  ;account for null character

Вы должны рассматривать символы как байты вместо слов.

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 вам нужно добавить соответствующий leave между popa а также ret,

В стрлен проще не использовать pusha, Таким образом, EAX можно вернуть!

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

Следующая строка, вероятно, опечатка. Поменять сб на sub,

sb      eax, ebx                ;subtract the final positions 
;***************************************************
;
; 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
Другие вопросы по тегам