Найти ошибку в программе удаления из строки слов, встречающихся 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

Объяснение кода листинга программы

  1. code_to_symbol proc - данная инструкция является процедурой, которая преобразует символ в код. В данном случае, она вычисляет смещение символа в таблице символов ASCII и возвращает его в регистре dl.
  2. len macro str - это макрос, который вычисляет длину строки str. Он сохраняет длину строки в регистре cx.
  3. copy macro src, dest, index, length - данный макрос копирует length символов из строки src с позиции index в строку dest.
  4. concat macro in1, in2, out - этот макрос объединяет строки in1 и in2 в одну строку out.
  5. getpos macro subs, inz - данный макрос находит позицию подстроки subs в строке inz. Он использует регистры bx, dx, di и si для хранения промежуточных значений.
  6. read macro size - этот макрос считывает целое число из стандартного ввода, представленного в шестнадцатеричной системе счисления, и сохраняет его в регистре dx.
  7. readln macro ofst - данный макрос считывает строку из стандартного ввода и сохраняет ее в буфере, указанном по смещению ofst.
  8. readstr macro string_x - этот макрос считывает строку из стандартного ввода и сохраняет ее в переменной string_x.
  9. write macro symbol_x - данный макрос выводит символ symbol_x в стандартный вывод.
  10. writeln macro string_x - этот макрос выводит строку string_x в стандартный вывод.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

11   голосов , оценка 4.182 из 5
Похожие ответы