Найти ошибку в программе удаления из строки слов, встречающихся n раз - Assembler
Формулировка задачи:
Добрый день. Помогите, пожалуйста, найти и исправить ошибку в программе (TASM). Она должна удалить из введённой строки слова, которые встречаются заданное число раз. Код написан, есть даже рабочий вариант на паскале, но всё равно не могу добиться верного результата в общем случае. Код основной программы:
Код подключаемого файла (library.asm) в сообщении ниже. Код на паскале:
И ещё один момент: проверяемая строка должна вводиться пользователем с клавиатуры, но у меня почему-то не выходит сделать этот простой момент. Пробовал через 0ah, 3fh, но результат некорректный. Процедуры для этих способов тоже есть в подключаемом файле, подскажите ошибку.
Решение задачи: «Найти ошибку в программе удаления из строки слов, встречающихся n раз»
textual
Листинг программы
code_to_symbol proc ; Puts symbol to dl. cmp dl, 41h ; capital 'A' jge doletter sub dx, 30h jmp return doletter: cmp dl, 61h ; small 'a' jge dosmall sub dx, 37h jmp return dosmall: sub dx, 57h return: ret code_to_symbol endp len macro str ; Calculates length of 'str', result in cx. push di push ax lea di, str mov cx, 0ffffh mov al, 24h ; 24h 'dollar', 20h 'space' cld repnz scasb not cx dec cx pop ax pop di endm copy macro src, dest, index, length ; Copies 'length 'symbols from 'index' position of 'src' string to 'dest'. push di push si push ax lea si, src add si, index dec si lea di, dest mov cx, length cld rep movsb mov ax, 24h ; 'dollar' to mark the end of the string stosb pop ax pop si pop di endm concat macro in1, in2, out ; Concatenates 'in1' and 'in2' to 'out'. push di push si lea si, in1 lea di, out len in1 mov ax, 24h ; 'dollar' sign, preventing of marking this as the end of the sting cld rep movsb lea si, in2 len in2 rep movsb mov ax, 24h ; 'dollar' to mark the end of the string stosb pop si pop di endm getpos macro subs, inz ; Gets index of 'subs' in 'inz' then pushes it to stack. local @loop, @not_found, @finish push bx push dx push di push si lea di, inz len inz mov temp, di mov bx, cx ; length(inz) lea si, subs len subs mov dx, cx ; length(subs) @loop: push cx mov cx, bx ; unchecked symbols of inStr or cx, cx ; inStr checked, but are there symbols in subStr remaining? jz @not_found ; yes, this means "Not found" cld ; data goes onwards lodsb ; symbol from subStr to al repne scasb ; searching for an al symbol of subStr in inStr jnz @not_found ; there are no any -> "Not found" mov bx, cx ; there is one, number of unchecked symbols of inStr goes to bx pop cx ; remaining symbols of subStr loop @loop ; dec(cx) and loop again while cx > 0 ;writeln msg_ya push dx mov pos, di sub pos, dx mov dx, temp sub pos, dx inc pos ; defining index of subStr in inStr pop dx jmp @finish @not_found: ;writeln msg_na mov pos, 0 ; set index to zero if subStr not found @finish: pop si pop di pop dx pop bx push pos endm read macro size ; Reads a number from stdin (currently it's assumed the number is in hex) then pushes to stack. local @loop, @skiprol, @doror, @finish mov cx, size ; byte size @loop: mov ah, 01h ; waits for symbol to input, its code puts to al int 21h cmp al, 0dh ; 'Enter' je @doror mov dl, al call code_to_symbol movzx dx, dl or char, dx ; copies symbol to char add count, 01h cmp count, size ; byte size je @skiprol rol char, 4 @skiprol: loop @loop ; whole number is putting in char jmp @finish @doror: ror char, 4 @finish: write newline mov dx, char push dx mov char, 0h mov count, 0h endm readln macro ofst ; Receives a string from stdin. push bx mov ah, 3fh ; keyboard as a file xor bx, bx ; with 0 descriptor mov cx, 80 ; buffer size lea dx, ofst ; buffer address int 21h pop bx endm readstr macro string_x lea dx, string_x mov ah, 0ah int 21h endm write macro symbol_x ; Puts 'symbol_x' to stdout. mov dl, symbol_x mov ah, 02h int 21h endm writeln macro string_x ; Puts 'string_x' to stdout. lea dx, string_x mov ah, 09h int 21h endm
Объяснение кода листинга программы
code_to_symbol proc
- данная инструкция является процедурой, которая преобразует символ в код. В данном случае, она вычисляет смещение символа в таблице символов ASCII и возвращает его в регистреdl
.len macro str
- это макрос, который вычисляет длину строкиstr
. Он сохраняет длину строки в регистреcx
.copy macro src, dest, index, length
- данный макрос копируетlength
символов из строкиsrc
с позицииindex
в строкуdest
.concat macro in1, in2, out
- этот макрос объединяет строкиin1
иin2
в одну строкуout
.getpos macro subs, inz
- данный макрос находит позицию подстрокиsubs
в строкеinz
. Он использует регистрыbx
,dx
,di
иsi
для хранения промежуточных значений.read macro size
- этот макрос считывает целое число из стандартного ввода, представленного в шестнадцатеричной системе счисления, и сохраняет его в регистреdx
.readln macro ofst
- данный макрос считывает строку из стандартного ввода и сохраняет ее в буфере, указанном по смещениюofst
.readstr macro string_x
- этот макрос считывает строку из стандартного ввода и сохраняет ее в переменнойstring_x
.write macro symbol_x
- данный макрос выводит символsymbol_x
в стандартный вывод.writeln macro string_x
- этот макрос выводит строкуstring_x
в стандартный вывод.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д