Форум программистов, компьютерный форум, киберфорум
Assembler для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.63/8: Рейтинг темы: голосов - 8, средняя оценка - 4.63
0 / 0 / 0
Регистрация: 06.04.2016
Сообщений: 6
1

Вывести на экран символы, которые содержатся в обеих строках

16.09.2017, 21:15. Показов 1487. Ответов 12

Author24 — интернет-сервис помощи студентам
Здравствуйте! Нужна помощь с программой. Пишу под DOS. Условие: С клавиатуры вводятся две строки, вывести на экран символы, которые содержатся в обеих строках. Вот мой код, работает неправильно, не совсем разобрался с регистром si, а точнее тем, как с ним взаимодействовать.

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
data segment
     string1 db 100,100 dup ('$') ; буфер ввода
     string2 db 100,100 dup ('$')  ; буфер ввода
     string3 db 100,100 dup ('$') ; буфер вывода
     len1 dw ?
     len2 dw ?
data ends
code segment
assume cs:code, ds:data
START:
        mov ax, data
        mov ds, ax
        mov dl, 0ah
        mov ah, 2
        int 21h
        lea dx, string1
        mov ah, 0ah
        int 21h 
        xor ah, ah 
        lea bx, string1+2 
        xor cx, cx
        mov cl, string1+1
        xor si, si
        mov len1, cx
BB1:
        mov al, [bx]
        mov string1[si] , al
        inc si
        inc bx 
loop BB1 ; окончание ввода 1й строки
        mov dl, 0ah
        mov ah, 2
        int 21h
        lea dx, string2
        mov ah, 0ah
        int 21h 
        xor ah, ah 
        lea bx, string2+2 
        xor cx, cx
        mov cl, string2+1
        xor si, si
        mov len2, cx
BB2:
        mov al, [bx]
        mov string2[si] , al
        inc si
        inc bx 
loop BB2 ; окончание ввода 2й строки
        mov dl, 0ah
        mov ah, 2
        int 21h
        xor bx, bx
        xor si, si
        xor di, di
        xor dx, dx
compare:
        cmp si, len1 ; как только дойдем до конца первой строки, выход
        je OUT1
        mov ah, string1[si] ; в ah - элемент из 1й строки
 
cmp1:
        mov al, string2[di] ; в al - элемент из 2й строки
        cmp ah, al
        jne NO
        mov string3[si], al ; если совпали, заношу элемент в строку на вывод
        jmp NEXT_SI
NO:
        cmp di, len2
        jl NEXT_DI
NEXT_SI:
        inc si
        xor di, di
        jmp compare
NEXT_DI:
        inc di
        jmp cmp1
loop compare
OUT1:
        mov string3[si], '$'
        xor si, si
        lea dx, string3
        mov ah, 09h
        int 21h
        mov ah, 10h
        int 16h
        mov ax, 4C00h 
        int 21h
 code ends
 end START
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.09.2017, 21:15
Ответы с готовыми решениями:

Ввести с клавиатуры две строки. Вывести на экран все символы, которые содержатся в обеих строках
Помогите пожалуйста, очень нужна эта программа к понедельнику

Ввести с клавиатуры две строки. Вывести на экран все символы, которые содержатся в обеих строках.
Условие программы: Ввести с клавиатуры две строки. Вывести на экран все символы, которые...

Вывести на экран только те символы, которые встречаются в обеих строках одновременно
Даны две строки А и В, которые содержат только маленькие и большие буквы русского и английского...

Вывести на экран слова, которые встречаются в обеих строках
вводится 2 строки. Как вывести на экран слова, которые встречаются в обеих строках? Помогите...

12
Эксперт Hardware
Эксперт Hardware
6103 / 2347 / 390
Регистрация: 29.07.2014
Сообщений: 3,108
Записей в блоге: 4
16.09.2017, 21:53 2
Цитата Сообщение от Silentium666 Посмотреть сообщение
Нужна помощь с программой
сам алгоритм программы неправильный. лучше организовать так..

1. вводишь строку(1) своей функцией(0Ah) сервиса DOS.
Эта fn. возвращает длину введённой строки во втором байте входного буфера(1). Кстати он у тебя оформлен не правильно.

2. вводишь строку(2), но теперь посимвольно в цикле, пока юзверь не нажмёт Enter.
Внутри цикла, каждый\введённый символ сразу ищешь в строке(1), длина которой у тебя уже есть. Если находишь этот символ, но сразу сохраняешь его в выходном буфере(2). Строку(2) даже сохранять не нужно..

Это проще реализуется, поскольку для поиска соответствий нужна будет одна инструкцией REPNE SCASB
1
0 / 0 / 0
Регистрация: 06.04.2016
Сообщений: 6
16.09.2017, 22:01  [ТС] 3
Подскажите пожалуйста, я в институте начал проходить эту дисциплину, не разобрался особо с вводом, поэтому так коряво написано. С циклом тоже не знаком. Вашу схему понял, понравилась, но сам не смогу реализовать. Можете дать хотя бы какие-нибудь наброски? Буду очень благодарен!
0
Модератор
Эксперт по электронике
8476 / 4335 / 1642
Регистрация: 01.02.2015
Сообщений: 13,461
Записей в блоге: 8
16.09.2017, 23:00 4
Посмотрите в https://www.cyberforum.ru/asm-... 05284.html разделы 13 и 17.

Добавлено через 7 минут
Есть ещё вариант.
Создаёте два битовых массива на 256 бит (8 байт).
1. Вводите 1-ю строку.
2. Просматриваете её в цикле и в 1-ом битовом массиве устанавливаете бит с номером очередного символа.
3. Вводите 2-ю строку.
4. Просматриваете её в цикле и в 2-ом битовом массиве устанавливаете бит с номером очередного символа.
5. Выполняете побитовое AND с битовыми массивами
6. Просматриваете битовый массив, и если бит установлен - выводите символ с кодом, равным номеру этого бита.

Данный вариант хорош тем, что выполняется за линейное время.
А также - что пункты 1, 2 повторяют пункты 3, 4 - т.е. можно организовать в виде подпрограммы (на крайний случай скопировать).

Добавлено через 1 минуту
На этапе отладки сами строки можно задать в программе - чтобы не отвлекаться на ввод.
1
0 / 0 / 0
Регистрация: 06.04.2016
Сообщений: 6
16.09.2017, 23:46  [ТС] 5
Хотел добавить, что не правильно выразился в своем ответе... с циклами знаком конечно, не знаю как реализовать посимвольный ввод через цикл. За все Ваши варианты, спасибо! Буду пробовать пока)
0
Модератор
Эксперт по электронике
8476 / 4335 / 1642
Регистрация: 01.02.2015
Сообщений: 13,461
Записей в блоге: 8
17.09.2017, 00:44 6
Попробуйте через множества. Такие структуры есть и в Pascal и в C++.
Битовый массив представляется через массив байт. Бит номер N находится в (N/8) байте по маске (1 << (N%8))
Где % - взятие остатка от деления, а << - сдвиг влево.


Кликните здесь для просмотра всего текста
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
data segment
     string1 db 100,100 dup ('$') ; буфер ввода
     string2 db 100,100 dup ('$')  ; буфер ввода
     string3 db 100,100 dup ('$') ; буфер вывода
     Set1       db      (256/8) dup(0)  ; битовый массив (множество символов 1-го слова)
     Set2       db      (256/8) dup(0)  ; битовый массив (множество символов 2-го слова)
     CrLf       db      0Dh, 0Ah, '$'   ; перевод строки
data ends
 
stk  segment para stack
        db      100h dup(?)
stk  ends
 
code segment
assume cs:code, ds:data
START:
        mov ax, data
        mov ds, ax
        ; перевод строки
        lea dx, CrLf
        mov ah, 09h
        int 21h
        ;ввод 1-й сторки
        lea dx, string1
        mov ah, 0ah
        int 21h
        lea dx, CrLf
        mov ah, 09h
        int 21h
        ;заполнение 1-го битового массива
        lea bx, Set1
        lea si, string1+2
        xor cx, cx
        mov cl, string1+1
For1:
        mov al, [si]    ; очередной символ
        mov ah, 0       ; получение битовой маски
        mov di, ax
        and ax, 07h
 
        mov dx, cx
        mov cl, 3
        shr di, cl
        mov cl, al
        mov al, 1
        shl al, cl
        mov cx, dx
 
        or  [bx + di], al
 
        inc si
        loop For1       ; окончание ввода 1-й строки
 
        ;ввод 2-й сторки
        lea dx, string2
        mov ah, 0ah
        int 21h
        lea dx, CrLf
        mov ah, 09h
        int 21h
        ;заполнение 2-го битового массива
        lea bx, Set2
        lea si, string2+2
        xor cx, cx
        mov cl, string2+1
For2:
        mov al, [si]    ; очередной символ
        mov ah, 0       ; получение битовой маски
        mov di, ax
        and ax, 07h
 
        mov dx, cx
        mov cl, 3
        shr di, cl
        mov cl, al
        mov al, 1
        shl al, cl
        mov cx, dx
 
        or  [bx + di], al
 
        inc si
        loop For2       ; окончание ввода 2-й строки
 
        ;вычисление пересечения множеств
        lea si, Set1
        lea di, Set2
        mov cx, (256/8)
Intersect:
        mov al, [di]
        and [si], al
        inc si
        inc di
        loop Intersect
 
        ;вывод общих для строк символов
        lea bx, Set1
        mov cx, 256
For3:
        mov dx, cx
 
        mov ax, 256     ; проверяемый символ
        sub ax, cx
 
        mov ah, 0       ; получение битовой маски
        mov di, ax
        and ax, 07h
 
        mov dx, cx
        mov cl, 3
        shr di, cl
        mov cl, al
        mov al, 1
        shl al, cl
 
        mov cx, dx
 
        mov dl, [bx + di]
 
        test [bx + di], al
        jz  Skip
        push ax
        push dx
        mov  ah, 02h
        mov  dx, 256
        sub  dx, cx
        int  21h
        pop  ax
        pop  dx
Skip:
        loop For3
 
        ; ожидание нажатия любой клавиши
        mov ah, 10h
        int 16h
        ; завершение программы
        mov ax, 4C00h
        int 21h
 code ends
 end START


Добавлено через 2 минуты
Это можно сделать и значительно короче, но у меня нет уверенности в том, что вы изучали команды битовых операций и в том, что ваш эмулятор DOS их будет поддерживать.
1
Эксперт Hardware
Эксперт Hardware
6103 / 2347 / 390
Регистрация: 29.07.2014
Сообщений: 3,108
Записей в блоге: 4
17.09.2017, 06:58 7
вот тебе набросок на FASM'е, под масм переделай сам.
это сом-файл, поэтому не нужно определять сегментные регистры в начале.
и посмотри на буфер для строки(1) под fn.0Ah. он состоит из 3-х составляющих, а не двух как у тебя:

- в нулевом байте(80) указывается макс.длина строки;
- в первом байте(0) после твоего ввода будет лежать реальная длина;
- начиная со-второго байта разворачивается сам буфер (DUP) - повторить нуль 80-раз.

знак($) - это маркер конца строки для fn.09h. т.к. заранее не известно, сколько ляжет в выходной буфер, то логично забить весь буфер(2) маркерами конца и затирать их найденными символами. в конце получим этот\злополучный маркер автоматически:

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
;fasm-code
;-----------
org   100h
jmp   start
 
str1    db    13,10,'String: $'
buff1   db    80,0,80 dup(0)       ; вх\буфер для fn.0Ah
buff2   db    80 dup('$')          ; вых\буфер
 
start:  mov   ah,9                 ; запрос на ввод(1)..
        mov   dx,str1
        int   21h
 
        mov   ah,0Ah               ; ввод сроки(1)
        mov   dx,buff1
        int   21h
 
        mov   ah,9                 ; запрос на ввод(2)..
        mov   dx,str1
        int   21h
 
        xor   cx,cx
        mov   cl,[buff1+1]
        inc   cx                   ; длина строки(1)
        mov   bx,cx                ;    ..(запомнить)
        mov   dx,buff1+2           ; адрес строки(1)
        mov   si,buff2             ; приёмник найденых
 
;--- начало цикла ----------//
@@1:    mov   ah,1                 ; ввод символа с эхом
        int   21h                  ;    ..(символ лежит в AL)
        cmp   al,13                ; это интер? 
        je    @stop
        mov   cx,bx                ; поиск символа в строке
        mov   di,dx                ; СХ-длина, DI-адрес для поиска
        repne scasb                ; поиск AL в DI длинною СХ..
        or    cx,cx                ; нашли?
        jz    @@2                  ; нет..
        mov   byte[si],al          ; иначе: сохраняем символ в буфере(2)
        inc   si                   ; буфер +1
@@2:    jmp   @@1                  ; в начало цикла..
 
@stop:  mov   ah,9                 ; результат!
        mov   dx,str1
        int   21h
 
        mov   ah,9
        mov   dx,buff2
        int   21h
 
        xor   ax,ax                ; ждём клаву..
        int   16h
        ret                        ; на выход!
1
0 / 0 / 0
Регистрация: 06.04.2016
Сообщений: 6
17.09.2017, 11:26  [ТС] 8
Павел, спасибо! Можете пояснить, что такое segment stack и почему, когда вводишь только буквы, вывод происходит в обратном порядке, а когда выводятся цифры, в прямом ?) видел работу со стеком, но так и не понял, почему через раз это все происходит.
0
0 / 0 / 0
Регистрация: 06.04.2016
Сообщений: 6
17.09.2017, 11:28  [ТС] 9
R71MT, спасибо! Подскажите, в чем может быть ошибка, скопировал Ваш код, записал в .com и запускаю на win7 x32, вот скрин ошибки
Миниатюры
Вывести на экран символы, которые содержатся в обеих строках  
0
Эксперт Hardware
Эксперт Hardware
6103 / 2347 / 390
Регистрация: 29.07.2014
Сообщений: 3,108
Записей в блоге: 4
17.09.2017, 13:26 10
не знаю. у меня fasm-1.67 а ось ХР_32 - всё работает.
а зачем тебе готовый файл? ты возьми с моего исходника код, и добавь его в свой исходник. яж тебе для этого привёл его..
1
Модератор
Эксперт по электронике
8476 / 4335 / 1642
Регистрация: 01.02.2015
Сообщений: 13,461
Записей в блоге: 8
17.09.2017, 15:45 11
Silentium666, вряд ли в моём исходнике такой эффект
Цитата Сообщение от Silentium666 Посмотреть сообщение
когда вводишь только буквы, вывод происходит в обратном порядке, а когда выводятся цифры, в прямом ?
Вывод происходит в порядке расположения кодов ASCII.

Т.к. программа имеет тип exe, то обязательно объявление сегмента стека. Если бы программа была типа com - то явное объявление не требуется. Пока примите это, как заклинание.

Переработайте собственную программу по совету R71MT и в случае ошибки работы приводите исходник.
Смысл поступить так в том, что вы разберётесь с темой.

Добавлено через 18 минут
Есть смысл доработать программу R71MT - поиск символа выполнять не только в первой строке, но и в результирующей - чтобы исключить повторы символов в ответе.

Эта доработка - буквально несколько строк.
1
0 / 0 / 0
Регистрация: 06.04.2016
Сообщений: 6
17.09.2017, 23:59  [ТС] 12
Очень помогли коды R71MT и ФедосеевПавел, не смог доработать Ваши коды, однако добавил в свой код некоторые Ваши идеи)) В итоге получилось, возможно громоздко, некоторые моменты так и не понял, на данном этапе своих знаний. Однако все работает, правда есть небольшой косячек с повторениями в выходной строке. Есть идеи, как легче и лучше реализовать?
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
data segment
     string1 db 80,0,80 dup(0)  ; ввод
     string2 db 80 dup('$')     ; вывод
     len dw ?
data ends
code segment
assume cs:code, ds:data
START:
        mov ax, data
        mov ds, ax
        mov dl, 0ah
        mov ah, 2
        int 21h
        lea dx, string1
        mov ah, 0ah
        int 21h
        xor ah, ah
        lea bx, string1+2
        xor cx, cx
        xor si, si
        mov cl, string1+1
        mov len, cx
STR1:
        mov al, [bx]
        mov string1[si], al
        inc si
        inc bx
loop STR1
        mov dl, 0ah
        mov ah, 2
        int 21h
        lea si, string2
        xor di, di
STR2:
        mov ah, 1
        int 21h
        cmp al, 13
        je EXIT
COMPARE:
        mov ah, string1[di]
        inc di
        cmp ah, al
        jne NO
        cmp ah, [si-1]
        je STR2
        cmp ah, [si+1]
        je STR2
        mov [si], al
        inc si
        xor di, di
        jmp STR2
NO:
        cmp len, di
        jg NEXT
        xor di, di
        jmp STR2
NEXT:
        jmp COMPARE
EXIT:
        mov ah,9
        lea dx, string2
        int 21h
        xor ax,ax
        int 16h
        mov ax, 4C00h 
        int 21h
 code ends
 end START
0
Модератор
Эксперт по электронике
8476 / 4335 / 1642
Регистрация: 01.02.2015
Сообщений: 13,461
Записей в блоге: 8
18.09.2017, 07:56 13
Добавьте описание сегмента стека.

Для работы цепочечных строковых команд настройте регистр ES.
Assembler
1
2
    mov ax, ds
     mov es, ax
Поиск нового символа выполняйте дважды - в 1-й строке, и в выходной строке. Сам поиск выполняйте repne scasb. Описание команды в Электронном учебнике. Сам смысл лабы - в изучении строковых команд.
1
18.09.2017, 07:56
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
18.09.2017, 07:56
Помогаю со студенческими работами здесь

Строка: Вывести все символы, которые встречаются в обеих строках, в порядке возрастания их ASCII-кодов
Здравствуйте, необходимо написать программу, которая находит все символы, встречающиеся в обеих...

Получить третью строку, состоящую из слов, которые содержатся в обеих строках
Даны две строки, состоящие из слов. Получить третью строку, состоящую из слов, которые содержатся в...

Вывести слова, которые встречаются в обеих строках
Даны две символьные строки. Слово - последовательность символов между пробелами, не содержащая...

Вывести слова, которые встречаются в обеих строках
Даны две символьные строки. Слово - последовательность символов между пробелами, не содержащая...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru