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

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

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 21.11.2022, 12:12   #1
ChestIotVaga
Пользователь
 
Регистрация: 21.11.2022
Сообщений: 84
Вопрос Помощь с выводом приглашения

помогите написать код со следующим алгоритмом:
− вывести на экран приглашение, и ввести с клавиатуры символьную
подстроку для поиска;
− вывести на экран еще одно приглашение, и ввести с клавиатуры
символьную строку с именем файла;
− открыть файл, прочитать его в буфер и найти в содержимом подстроку,
используя строковые инструкции;
− вывести результат поиска в виде сообщения «Найдено» или «Не найдено»;
− завершить программу.
очень нужна помощь буду очень благодарен.


Код:
  .model small
    .code
 
;
; CALL PTHIS
; db 'Hello World!', 0
;
PTHIS:
MOV     CS:temp1, SI  ; store SI register.
POP     SI            ; get return address (IP).
PUSH    AX            ; store AX register.
push    dx
next_char:      
        MOV     AL, CS:[SI]
        INC     SI            ; next byte.
        CMP     AL, 0
        JZ      printed        
        MOV     AH, 2  ; эряхўрЄрЄ№ ёшьтюы
        mov     dl,al
        INT     21h
        JMP     next_char     ; loop.
printed:
pop     dx
POP     AX            ; re-store AX register.
; SI should point to next command after
; the CALL instruction and string definition:
PUSH    SI            ; save new return address into the Stack.
MOV     SI, CS:temp1  ; re-store SI register.
RET
temp1  DW  ?    ; variable to store original value of SI register.
 
; ввод строки в переменную buf длиной buflen
input   macro buf,buflen
     local m1
     jmp short m1
     db buflen+1
     db 0
buf  db buflen+1 dup (0)
m1:  mov dx,offset buf-2 ; ввод строки
     mov ah,0Ah
     int 21h
     endm
 
file dw 0 ; дескриптор файла
filesize dw 0 ; длина прочитанного файла
findlen  dw 0 ; длина строки поиска
found    db 0 ; флаг "строка найдена"
 
start: push cs
    pop ds
    push cs
    pop es
        call pthis
        db 13,10,"Find>",0
        input finds,64
        mov di,offset finds
        mov cl,[di-1]
        mov ch,0
        mov findlen,cx
        cmp cl,0
        jnz cont1 
        jmp exerr
cont1:  add di,cx
        mov [di],ch ; [di]=0 - конец строки
    call pthis
    db 13,10,"File>",0
        input finame,64
        mov di,offset finame
        mov cl,[di-1]
        mov ch,0
        jcxz exerr
    add di,cx
        mov [di],ch ; [di]=0 - конец строки
    mov dx,offset finame
    mov ax,3D00h ; открыть файл для чтения
        int 21h
        jc  erropen ; выход по ошибке
    mov file,ax ; сохранить дескриптор файла
 
        mov bx,file
; Для простоты мы читаем файл только 1 раз в достаточно длинный буфер
        mov cx,8000h ; макс длина фрагмента чтения (пример)
    mov dx,offset filebuf
    mov ah,3Fh   ; читать файл Если длина файла <= cx он будет прочитан целиком
        int 21h
        jc  eread   ; выход по ошибке чтения
        mov filesize,ax ; сколько байт прочитано (нет ошибки)
; теперь в ОЗУ по адресу filebuf длиной filesize байт находится прочитанный файл
    mov bx,file ; закрыть файл. По окончании работы с файлом его обязательно надо закрыть.
        mov ah,3Eh
        int 21h
        call findstr ; поиск строки в файле
        mov ax,4C00h ; выход в Дос
        int 21h
 
; Ошибки можно обрабатывать более сложно, используя код ошибки AX
erropen:call pthis
        db 13,10, "Cant open file",0 ; Файл невозможно открыть для чтения, если нет файла с таким именем
exerr:  mov ax,4C01h
        int 21h
eread:  call pthis
        db 13,10, "Cant read file",0 ; Например, если не читается файл на флопике.
    jmp exerr
 
findstr:
; поиск подстроки в строке
    mov found,0
    mov cx,filesize
        sub cx,findlen
    jc out_result ; данные в файле короче строки поиска
        inc cx
    cld
        mov di,offset filebuf
        mov al,finds ; al=первый символ искомой строки
search1:cmp al,[di]
    jnz search2
    push cx ; первый символ найден
        push di
        mov si,offset finds
        mov cx,findlen
        repe cmpsb ; найдена ли строка целиком ?
        jne search3
        mov found,1 ; да
search3:pop di
        pop cx
search2:inc di ; следующий символ файла
        loop search1
out_result:
        cmp found,0
        jz text_no
        call pthis
        db 13,10,"Found !",0
        ret
text_no:call pthis
        db 13,10,"Not found",0
        ret
 
filebuf label byte
 
    end start
ChestIotVaga вне форума Ответить с цитированием
Старый 21.11.2022, 12:55   #2
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

Цитата:
Сообщение от ChestIotVaga Посмотреть сообщение
Код:
PTHIS:
MOV     CS:temp1, SI  ; store SI register.
POP     SI            ; get return address (IP).
PUSH    AX            ; store AX register.
push    dx
next_char:      
        MOV     AL, CS:[SI]
        INC     SI            ; next byte.
        CMP     AL, 0
        JZ      printed        
        MOV     AH, 2  ; эряхўрЄрЄ№ ёшьтюы
        mov     dl,al
        INT     21h
        JMP     next_char     ; loop.
printed:
pop     dx
POP     AX            ; re-store AX register.
; SI should point to next command after
; the CALL instruction and string definition:
PUSH    SI            ; save new return address into the Stack.
MOV     SI, CS:temp1  ; re-store SI register.
RET
temp1  DW  ?    ; variable to store original value of SI register.
Что за жуть вы тут устроили. Лень метку придумать для определения текстовой константы? Это очень плохой подход, даже не надо к такому привыкать.

Цитата:
Сообщение от ChestIotVaga Посмотреть сообщение
Код:
mov bx,file
; Для простоты мы читаем файл только 1 раз в достаточно длинный буфер
        mov cx,8000h ; макс длина фрагмента чтения (пример)
    mov dx,offset filebuf
    mov ah,3Fh   ; читать файл Если длина файла <= cx он будет прочитан целиком
        int 21h
А если длина файла больше 32 кб?

Цитата:
Сообщение от ChestIotVaga Посмотреть сообщение
Код:
search1:cmp al,[di]
Если надо использовать строковые команды, тогда проще написать repne scasb

Код:
findstr: ; Поиск строки с использованием строковых инструкций. Возвращает 0 в ax, если строка не найдена иначе ax = 1.
    mov si, offset finds
    mov cx, filesize
    mov di, offset filebuf
    sub cx, findlen
    jb not_found
    cld
    lodsb ; Считали первый символ из искомой строки
test_cycle:
    repne scasb ; Ищем первый символ в буфере
    jnz not_found ; До конца буфера не нашлось первого символа искомой строки
    push cx
    push si
    mov cx, findlen
    push di
    dec cx
    repe cmpsb ; Сравниваем остаток строки без первого символа со строкой в буфере
    pop di
    pop si
    pop cx
    jnz test_cycle ; Не совпало (продолжаем)
    mov ax, 1
    ret
not_found:
    xor ax, ax
    ret

Последний раз редактировалось macomics; 21.11.2022 в 13:07.
macomics вне форума Ответить с цитированием
Старый 21.11.2022, 13:37   #3
ChestIotVaga
Пользователь
 
Регистрация: 21.11.2022
Сообщений: 84
По умолчанию

извините первый раз сталкиваюсь с ассемблером и чутка не понимаю некоторые моменты
ChestIotVaga вне форума Ответить с цитированием
Старый 21.11.2022, 13:39   #4
ChestIotVaga
Пользователь
 
Регистрация: 21.11.2022
Сообщений: 84
По умолчанию

То есть как я понял вот целый код теперь будет работать?
Код:
    .model small
    .code
 
;
; CALL PTHIS
; db 'Hello World!', 0
;
PTHIS:
MOV     CS:temp1, SI  ; store SI register.
POP     SI            ; get return address (IP).
PUSH    AX            ; store AX register.
push    dx
next_char:      
        MOV     AL, CS:[SI]
        INC     SI            ; next byte.
        CMP     AL, 0
        JZ      printed        
        MOV     AH, 2  ; эряхўрЄрЄ№ ёшьтюы
        mov     dl,al
        INT     21h
        JMP     next_char     ; loop.
printed:
pop     dx
POP     AX            ; re-store AX register.
; SI should point to next command after
; the CALL instruction and string definition:
PUSH    SI            ; save new return address into the Stack.
MOV     SI, CS:temp1  ; re-store SI register.
RET
temp1  DW  ?    ; variable to store original value of SI register.
 
; ввод строки в переменную buf длиной buflen
input   macro buf,buflen
     local m1
     jmp short m1
     db buflen+1
     db 0
buf  db buflen+1 dup (0)
m1:  mov dx,offset buf-2 ; ввод строки
     mov ah,0Ah
     int 21h
     endm
 
file dw 0 ; дескриптор файла
filesize dw 0 ; длина прочитанного файла
findlen  dw 0 ; длина строки поиска
found    db 0 ; флаг "строка найдена"
 
start: push cs
    pop ds
    push cs
    pop es
        call pthis
        db 13,10,"Find>",0
        input finds,64
        mov di,offset finds
        mov cl,[di-1]
        mov ch,0
        mov findlen,cx
        cmp cl,0
        jnz cont1 
        jmp exerr
cont1:  add di,cx
        mov [di],ch ; [di]=0 - конец строки
    call pthis
    db 13,10,"File>",0
        input finame,64
        mov di,offset finame
        mov cl,[di-1]
        mov ch,0
        jcxz exerr
    add di,cx
        mov [di],ch ; [di]=0 - конец строки
    mov dx,offset finame
    mov ax,3D00h ; открыть файл для чтения
        int 21h
        jc  erropen ; выход по ошибке
    mov file,ax ; сохранить дескриптор файла
 
        mov bx,file
; Для простоты мы читаем файл только 1 раз в достаточно длинный буфер
        mov cx,8000h ; макс длина фрагмента чтения (пример)
    mov dx,offset filebuf
    mov ah,3Fh   ; читать файл Если длина файла <= cx он будет прочитан целиком
        int 21h
        jc  eread   ; выход по ошибке чтения
        mov filesize,ax ; сколько байт прочитано (нет ошибки)
; теперь в ОЗУ по адресу filebuf длиной filesize байт находится прочитанный файл
    mov bx,file ; закрыть файл. По окончании работы с файлом его обязательно надо закрыть.
        mov ah,3Eh
        int 21h
        call findstr ; поиск строки в файле
        mov ax,4C00h ; выход в Дос
        int 21h
 
; Ошибки можно обрабатывать более сложно, используя код ошибки AX
erropen:call pthis
        db 13,10, "Cant open file",0 ; Файл невозможно открыть для чтения, если нет файла с таким именем
exerr:  mov ax,4C01h
        int 21h
eread:  call pthis
        db 13,10, "Cant read file",0 ; Например, если не читается файл на флопике.
    jmp exerr
 
findstr: ; Поиск строки с использованием строковых инструкций. Возвращает 0 в ax, если строка не найдена иначе ax = 1.
    mov si, offset finds
    mov cx, filesize
    mov di, offset filebuf
    sub cx, findlen
    jb not_found
    cld
    lodsb ; Считали первый символ из искомой строки
test_cycle:
    repne scasb ; Ищем первый символ в буфере
    jnz not_found ; До конца буфера не нашлось первого символа искомой строки
    push cx
    push si
    mov cx, findlen
    push di
    dec cx
    repe cmpsb ; Сравниваем остаток строки без первого символа со строкой в буфере
    pop di
    pop si
    pop cx
    jnz test_cycle ; Не совпало (продолжаем)
    mov ax, 1
    ret
not_found:
    xor ax, ax
    ret
ChestIotVaga вне форума Ответить с цитированием
Старый 21.11.2022, 18:40   #5
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

После команды call findstr вы не обрабатываете результат. Надо проверить:
Код:
    call findstr
    test ax, ax
    jz show_not_found
    call pthis
  db 13, 10, "Found", 0
    mov ax, 4C00h
    int 21h

show_not_found:
    call pthis
  db 13, 10, "Not found", 0
    mov ax, 4C00h
    int 21h
macomics вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Нужна помощь с выводом строки, C++ Fronzi Общие вопросы C/C++ 5 22.03.2017 19:01
Приглашения в проект... Алексе Помощь студентам 1 25.08.2012 17:36
Помощь с BASS, сигналом и выводом графики Манжосов Денис :) Мультимедиа в Delphi 7 12.01.2011 15:25
Код приглашения для habrahabr spamer Свободное общение 33 30.10.2009 14:49
Помощь с выводом в файл FatalX Помощь студентам 1 14.07.2008 19:23