Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 13.05.2014, 14:42   #1
yeolus
Новичок
Джуниор
 
Регистрация: 13.05.2014
Сообщений: 2
По умолчанию Найти ошибку в программе удаления из строки слов, встречающихся n раз

Добрый день.
Помогите, пожалуйста, найти и исправить ошибку в программе (TASM). Она должна удалить из введённой строки слова, которые встречаются заданное число раз. Код написан, есть даже рабочий вариант на паскале, но всё равно не могу добиться верного результата в общем случае.
Код основной программы:
Код:
masm
model medium
.386
.data
	temp dw (?)
	char dw 0h
	count dw 0h
	n dw (?)
	k dw (?)
	i dw (?)
	wc dw (?)
	msg_in db "Enter a string: $"
	msg_n db "How many recurring words to remove: $"
	msg_out db "Result: $"
	inzStr db "ref abcd ret abcd ter hunder$" ;80 dup(?)
	tmpStr1 db 80 dup(?)
	tmpStr2 db 80 dup(?)
	outStr db 80 dup(?)
	wordTemp db 80 dup(?)
	pos dw 0h
	newline db 0ah
	space db " $"
	blank db "$"	
.stack 100h
.code
assume ds:@data, es:@data
include library.asm
main:
	mov ax, @data
	mov ds, ax
	mov es, ax
                                            	
	copy space outStr 1 1
	;writeln msg_in
	;readln inzStr
	writeln msg_n
	read 2
	pop n
	concat inzStr space inzStr
	getpos space inzStr
	pop k
	
@kloop:
	cmp k, 0
	jng @ending

	mov dx, k
	dec dx
	copy inzStr wordTemp 1 dx
	
	mov dx, k
	inc dx
	copy inzStr inzStr dx 80h
	
	copy space tmpStr1 1 1
	copy space tmpStr2 1 1
	concat tmpStr1 wordTemp tmpStr1
	concat tmpStr1 space tmpStr1
	concat tmpStr2 inzStr tmpStr2
	getpos tmpStr1 tmpStr2
	pop i
	
	mov wc, 1
	
	@iloop:
		cmp i, 0
		jng @icont
	          
	 	inc wc
	 	
	 	mov dx, i
	 	dec dx
		copy inzStr tmpStr1 1 dx
		len wordTemp
		mov dx, i
		add dx, cx
		inc dx
		copy inzStr tmpStr2 dx 80h
		concat tmpStr1 tmpStr2 inzStr

		copy space tmpStr1 1 1
		copy space tmpStr2 1 1
		concat tmpStr1 wordTemp tmpStr1
		concat tmpStr1 space tmpStr1
		concat tmpStr2 inzStr tmpStr2

		getpos tmpStr1 tmpStr2
		pop i
		
		jmp @iloop		
	
	@icont:
	    	
	mov dx, n
	cmp wc, dx
	jne @cont
		
	copy blank wordTemp 1 1
		
	jmp @fin
	          
	@cont:
	concat outStr space outStr
	
	@fin:
	concat outStr wordTemp outStr
	;writeln outStr
	;write newline
	
	getpos space inzStr
	pop k

	jmp @kloop
	
	@ending:
		
        	writeln msg_out
        	writeln outStr
		
	mov ah, 01h
	int 21h
	
	mov ax, 4c00h
	int 21h	
end main
Код подключаемого файла (library.asm) в сообщении ниже.
Код на паскале:
Код:
var 
  inStr, wordTemp, outStr: string;
  k, i, wc, n: byte;
begin
  readln(inStr);
  writeln;
  inStr := inStr + ' ';
  outStr := '';
  read(n);
  k := Pos(' ', inStr);
  while (k > 0) do begin
    wordTemp := copy(inStr, 1, k-1);
    inStr := copy(inStr, k+1, 255);
    i := Pos(' ' + wordTemp + ' ', ' ' + inStr);
    wc := 1;
    while (i > 0) do begin
      inc(wc);
      inStr := copy(inStr, 1, i-1) + copy(inStr, i+length(wordTemp)+1, 255);
      i := Pos(' ' + wordTemp + ' ', ' ' + inStr);
    end;
    if wc = n then begin
      wordTemp := '';
      outStr := outStr + wordTemp;
    end else
      outStr := outStr + ' ' + wordTemp;
    k := Pos(' ', inStr);
  end;
  writeln(outStr);
  readln;
end.
И ещё один момент: проверяемая строка должна вводиться пользователем с клавиатуры, но у меня почему-то не выходит сделать этот простой момент. Пробовал через 0ah, 3fh, но результат некорректный. Процедуры для этих способов тоже есть в подключаемом файле, подскажите ошибку.
yeolus вне форума Ответить с цитированием
Старый 13.05.2014, 14:43   #2
yeolus
Новичок
Джуниор
 
Регистрация: 13.05.2014
Сообщений: 2
По умолчанию

library.asm:
Код:
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
yeolus вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
найти ошибку в программе Александрq Помощь студентам 4 05.11.2012 01:47
найти ошибку в программе aleko05 Помощь студентам 6 07.10.2012 17:57
нужно исправить ошибку,двумерный массив,удаления строки ленок-носок Помощь студентам 0 24.03.2012 22:57
найти ошибку в программе (С++) Vally Помощь студентам 3 17.01.2012 18:08
Составить в алфавитном порядке список всех слов, встречающихся в тексте, и количество этих слов. KAPAHDAW Паскаль, Turbo Pascal, PascalABC.NET 2 17.02.2009 01:19