Счетчик циклов MASM отображает только «+0» (irvine32)

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

Переменная totalWords инициализируется значением 0 и увеличивается каждый раз, когда в строке встречается символ ' '.

Однако вывод всегда равен «+0» всякий раз, когда тестируется. Я знаю, что остальная часть скрипта работает, потому что он успешно изменяет регистр букв.

Как лучше всего увеличить переменную и отобразить ее?

INCLUDE Irvine32.inc

.data
    source BYTE 40 DUP (0)
    byteCount DWORD ?
    target BYTE SIZEOF source DUP('#')
    sentencePrompt BYTE "Please enter a sentence: ",0
    wordCountPrompt BYTE "The number of words in the input string is: ",0
    outputStringPrompt BYTE "The output string is: ",0
    totalWords DWORD 0                                                      ; SET TOTALWORDS VARIABLE TO 0 INITIALLY
    one DWORD 1
    space BYTE " ",0

.code
main PROC
    mov edx, OFFSET sentencePrompt
    call Crlf
    call WriteString
    mov edx, OFFSET source
    MOV ecx, SIZEOF source
    call ReadString
    call Crlf
    call Crlf
    call TRANSFORM_STRING
    call Crlf
    exit
main ENDP

TRANSFORM_STRING PROC
    mov esi,0
    mov edi,0
    mov ecx, SIZEOF source

    transformStringLoop:
        mov al, source[esi] 
            .IF(al == space)                
                inc totalWords                  ; INCREMENT TOTALWORDS DATA
                mov target[edi], al
                inc esi
                inc edi
            .ELSE
                .IF(al >= 64) && (al <=90)
                    add al,32
                    mov target[edi], al
                    inc esi
                    inc edi
                .ELSEIF (al >= 97) && (al <=122)
                    sub al,32
                    mov target[edi], al
                    inc esi
                    inc edi
                .ELSE
                    mov target[edi], al                 
                    inc esi
                    inc edi
                .ENDIF
            .ENDIF
        loop transformStringLoop
        mov edx, OFFSET wordCountPrompt
        call WriteString
        mov edx, OFFSET totalWords                              ; DISPLAY TOTALWORDS
        call WriteInt
        call Crlf
        mov edx, OFFSET outputStringPrompt
        call WriteString
        mov edx, OFFSET target
        call WriteString
        ret
TRANSFORM_STRING ENDP
END main

person Lou    schedule 13.05.2020    source источник


Ответы (1)


Эта часть неверна:

mov edx, OFFSET totalWords                              ; DISPLAY TOTALWORDS
call WriteInt

WriteInt не ожидает смещения в edx; он ожидает фактическое целочисленное значение в eax. Итак, код должен быть:

mov eax, totalWords                              ; DISPLAY TOTALWORDS
call WriteInt

Кроме того, ваша космическая переменная бессмысленна. Вы могли бы просто написать

.IF(al == ' ')

И ваш способ подсчета количества слов звучит немного неправильно. Строка типа "foo bar" содержит только 1 пробел, но два слова. Обратите внимание, что вы также не можете использовать number_of_spaces+1, потому что это даст неверный результат для таких строк, как " ", "foo bar" и "foo ".

Вы, вероятно, получите лучшие результаты с чем-то вроде:

if (al != ' ' && (esi == 0 || source[esi-1] == ' ')) totalWords++;

Это просто какой-то псевдокод для выражения идеи. Я оставлю это на ваше усмотрение, чтобы перевести это на сборку x86.

person Michael    schedule 13.05.2020
comment
Это было очень полезно! Спасибо - person Lou; 13.05.2020