Напишите код на ассемблере, чтобы перевернуть строку - PullRequest
0 голосов
/ 31 октября 2018

это код для обращения строки Я действительно изо всех сил пытаюсь закончить этот код. Я не мог найти, что с ним не так, однако вывод неправильный.

    mov esi, OFFSET source             
    mov edi, OFFSET target          
    add edi, SIZEOF target-2
    mov ecx, SIZEOF source-1   

L1:                             
    mov  al, [esi]              
    mov  [edi], al                
    inc  esi                      
    dec  edi                     
    loop L1                    

1 Ответ

0 голосов
/ 31 октября 2018

Немного странно, что вы передаете в функцию две длины. Все виды плохих вещей могут произойти, если два несовпадения. Лучше передать длину строки в явном виде или сделать так, чтобы код вычислил длину.
Поскольку получение длины старой c-строки в skool нетривиально для кода, но тривиально для Google, я просто передам ее в качестве параметра.

'... неверный вывод.'
Проблема в том, что ваши строки должны заканчиваться нулем, но вы не ставите конечный ноль в строке назначения.

Прежде всего, если вы хотите, чтобы строка была допустимой строкой в ​​стиле c, убедитесь, что вы добавили завершающий ноль, например так: source db "test test",0

    mov esi, OFFSET source        ;Start of source
    mov edi, OFFSET target        ;start of dest
    ;length EQU SIZEOF source      ;we are reversing source
    mov ecx, SIZEOF source        ;Length of the string 
                                  ;(includes the terminating 0)

Setup:
    ;//a c-string must have a terminating 0!
    xor eax,eax                   ;al=0, put the terminating zero in first   
L1:                             
    mov  [edi+ecx-1], al          ;if length(ecx)=1, then write to [edi] directly.  
    mov  al, [esi]               
    inc  esi                                           
    loop L1 

Замечания по коду
Нет необходимости держать в полете три счетчика (edi, esi, ecx), достаточно двух. esi обратный отсчет, ecx обратный отсчет.
В x86 есть много действительно полезных режимов адресации, которые в основном бесплатны.
Последняя итерация будет читать конечный ноль в al, нам не нужно менять это на обратное, и вы уже написали его в начале, поэтому он (молча) отбрасывается.
Из-за завершающего нуля длина равна по крайней мере 1. Это хорошо, потому что если вы каким-то образом будете вводить 0 в loop, это будет цикл 'навсегда'; не хорошо («навсегда» 4 миллиарда раз) .

Обратите внимание, что ваш код не учитывает Unicode, поэтому он не будет работать для UTF8, но давайте предположим, что это всего лишь учебное упражнение.

Если вы следуете ABI , то вы можете просто передать параметры в регистрах, то есть вы можете пропустить некоторые инициализации. Учитывая, что ваш код не получит никаких призов за скорость, я пропустил этот шаг.

...