Как написать цикл, который делает что-то другое в последней итерации? - PullRequest
0 голосов
/ 20 февраля 2019

Выход для данной программы должен быть 1--2--3--4--5--6--7--8.Тем не менее, мой продолжает давать мне 1--2--3--4--5--6--7-8 -. Мне нужно избавиться от "-" после 8, но я не мог понятькак это сделать.Может ли кто-нибудь помочь мне, пожалуйста?

INCLUDE Irvine32.inc 
.data

arrayb byte 1,2,3,4,5,6,7,8
space byte "--",0

.code
main PROC
    mov eax,0
    mov edx,offset space
    mov esi,offset arrayb

    mov ecx, 8      

    printb:

         mov al, [esi]
         call writedec
         call writestring
         inc esi
         mov eax, 8

    loop printb

exit
main ENDP

end main

1 Ответ

0 голосов
/ 20 февраля 2019

Ваш код (и, в частности, цикл) в настоящее время выполняет:

<init state>
counter = 8
printb:
  output number
  output "--"
  loop to printb
<exit>

Если вы пробежите по нему в голове, должно быть понятно, почему после последнего числа печатается знак "-".

Есть много способов, как настроить этот код, в реальном коде, выполняющем форматирование. Я часто либо использую какую-то функцию join, которая принимает список и разделитель и создает отформатированную строку, либо, если это делается вручную, я бы, вероятно,Жесткий код выводит «1» перед циклом, инициализирует состояние для запуска цикла, как если бы оно начиналось с «2», и выводит «-» как первое в цикле, то есть:

<init state>
output number
advance state as if it was printed inside loop
counter = 8-1   ; one value is already out
printb:
  output "--"   ; the loop body starts with "--" output
  output number
  loop to printb
<exit>

Т.е. вВаш код (с некоторыми изменениями, «улучшающими» некоторые вещи, которые мне не нравились:

...
mov   edx,offset space
mov   esi,offset arrayb
movzx eax, BYTE PTR [esi]
inc   esi
call  writedec
mov   ecx, 8-1

printb:
    call  writestring
    movzx eax, BYTE PTR [esi]
    inc   esi
    call  writedec
loop printb
exit
...

edit

Идея Питера Кордеса из комментариев сделать последний элемент частным случаем может бытьпривести к лучшему коду в общих случаях, когда количество элементов является переменным (с фиксированным «8» вы знаете, что вы можете отобразить первый элемент, а затем еще 7 будут зациклены).

Давайте представим такую ​​функцию в ассемблереmbly, принимая аргументы в регистрах:

; esi = byte array to output
; ecx = amount of bytes
; will modify eax, ecx, edx, esi
OutputByteArray PROC
    jecxz   NoItemsToOutput     ; if ecx=0
    dec     ecx
    jz      OutputLastItem      ; if ecx=1, display only last item
    ; 1 < count, so "0 < ecx" here (ecx = count-1) => do the loop
    mov     edx,offset space
printb:     ; output number and "--" "count-1" times
        movzx eax, BYTE PTR [esi]
        inc   esi
        call  writedec
        call  writestring
    loop    printb
OutputLastItem:
    movzx   eax, BYTE PTR [esi]
    call    writedec
NoItemsToOutput:
    ret
ENDP
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...