Ассемблер TASM. Нужно ввести строку и с помощу команд обработки цепочек подсчитать кол-во русской буквы «в» в строке

Ассемблер TASM. Нужно ввести строку и с помощу команд обработки цепочек подсчитать кол-во русской буквы «в» в строке

  1. Замечания к ответу res01.

    Во-первых, ни к чему устанавливать флаг нуля ZF командой or cx,cx, ведь есть команда jcxz, которая, не изменяя флагов, проверяет содержимое регистра cx на равенство нулю и производит переход по указанному адресу, если cx=0.
    То есть вместо
    emsp; repne scasb
    emsp; or cx,cx; или test cx,cx
    emsp; je ex
    можно написать
    emsp; repne scasb
    emsp; jcxz ex

    Во-вторых, команда repne scasb сама по себе устанавливает флаг ZF в зависимости от того, по какой причине произошл выход из этого микроцикла. Если ZF установлен, то найден искомый байт, если сброшен, то cx = 0.
    emsp; repne scasb
    emsp; jne ex

    В-третьих, если искомый байт находится на последней позиции, то конструкции
    emsp; repne scasb
    emsp; or cx,cx
    emsp; je ex
    и
    emsp; repne scasb
    emsp; jcxz ex
    его не посчитают.

    Программа (TASM, процессор i8086 и старше, реальный режим, 16-разрядное приложение MS DOS):

    .model small
    .stack 100h

    .code
    N78220854:
    emsp; emsp; mov ax,@data
    emsp; emsp; mov ds,ax
    emsp; emsp; mov es,ax
    emsp; emsp; mov ah,9
    emsp; emsp; lea dx,Prompt1
    emsp; emsp; int 21h
    emsp; emsp; inc ah
    emsp; emsp; lea dx,Buffer
    emsp; emsp; int 21h
    emsp; emsp; dec ah
    emsp; emsp; lea dx,Prompt2
    emsp; emsp; int 21h
    emsp; emsp; mov ah,1
    emsp; emsp; int 21h
    emsp; emsp; mov cl,LenStr
    emsp; emsp; xor ch,ch
    emsp; emsp; mov bl,ch
    emsp; emsp; lea di,String
    FindLoop:
    emsp; emsp; repne scasb
    emsp; emsp; jne Output
    emsp; emsp; inc bl
    emsp; emsp; jmp FindLoop
    Output:
    emsp; emsp; mov al,bl
    emsp; emsp; mov bh,10
    Prepare:
    emsp; emsp; xor ah,ah
    emsp; emsp; div bh
    emsp; emsp; add ah,30h
    emsp; emsp; push ax
    emsp; emsp; inc cx
    emsp; emsp; or al,al
    emsp; emsp; jnz Prepare
    emsp; emsp; mov ah,9
    emsp; emsp; lea dx,Result
    emsp; emsp; int 21h
    emsp; emsp; mov ah,2
    Print:
    emsp; emsp; pop dx
    emsp; emsp; mov dl,dh
    emsp; emsp; int 21h
    emsp; emsp; loop Print
    emsp; emsp; lea dx,ResUnit
    emsp; emsp; mov ah,9
    emsp; emsp; int 21h
    emsp; emsp; mov ah,8
    emsp; emsp; int 21h
    emsp; emsp; mov ah,4Ch
    emsp; emsp; int 21h

    .data
    MaxLen equ 79
    Prompt1 db Введите строку: ,13,10,36
    Prompt2 db 13,10,Введите искомый символ: ,36
    Result db 13,10,Заданный символ встречается в строке $
    ResUnit db раз. $
    Buffer db MaxLen + 1
    LenStr db ?
    String db MaxLen + 1 dup (?)

    emsp; emsp; end N78220854

  2. примерно как то так

    main:

    mov al,»в» ;символ для поиска
    cld
    lea di,string ;загрузка в es:di смещения строки
    mov cx,32 ;для префикса repne — длина строки
    ;поиск в строке (пока искомый символ и символ в строке не совпадут)
    failed:
    repne scasb string ;
    or cx,cx
    je ex
    inc _count ;подсчт символов
    jmp failed ;повтор цикла, если cx != 0