Форум программистов, компьютерный форум, киберфорум
Наши страницы
Assembler для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 5.00/6: Рейтинг темы: голосов - 6, средняя оценка - 5.00
Hou
0 / 0 / 0
Регистрация: 25.01.2018
Сообщений: 15
1

Сортировка и запись в файл строки, введённой с клавиатуры

25.01.2018, 19:00. Просмотров 1049. Ответов 33

Нужно рассортировать вводимые с клавиатуры символы на цифры и другие символы и записать в два файла
Я думала сделать через буфер, но не знаю, как туда записать, а потом из буфера в файл кинуть
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
code_seg segment
ASSUME CS:code_seg,DS:code_seg,ES:code_seg
org 100h
 
start: 
; create file
MOV AH, 3Ch ; CREATE создание файла
MOV CX, 0 ; 
MOV DX, OFFSET Filenum
INT 21H 
Mov HandlerNum, AX 
 
numbr DB 0 ; counter счетчик для чисел
othr db 0;      для других символов
len db 0
 
cycle: ;цикл
vvod proc near   ;vvod simbol into AL 
    mov len,30h          ; 
        mov AH, 01h   ;ввод с клавиатуры
        int 21h 
        mov bl,0Dh  
        cmp bl,al      ; проверка: если нажата клавиша enter
      je exit            ; то выход
        mov bl,27
        cmp bl,al      ;проверка: если нажата клавиша esc
      je exit            ;то выход
 
; проверяем число или нет
        ; check1 0<=AL<=9
        mov DH, 30h  ; DH=0
        cmp AL, DH   ; AL<DH?
      jc other          ; other
        mov DH, 3Ah  ; DH=9+1ascii
        cmp AL, DH   ; AL<DH?
      jc number      ; it is number
      jc other
 
other: 
;count
add othr, 1
;здесь по аналогу с цифрами вставлю
jmp cycle  ;возвращаю в цикл
 
number:
;count счетчик, вдруг понадобится
add numbr, 1  
 
bufnum db ' '  ; вроде как буфер
;
;   здесь должна быть запись из AL в буфер
;
mov  ah,40h        ; это вроде как запись в файл, но оно кидает в файл что-то непонятное
mov  bx,handlernum    
mov  cx,3        
lea dx,bufnum
mov ah,3eh
mov bx,handlernum
int 21h
 
jmp cycle   ; возвращаем в цикл
 
 
;NUMBER    
 
    BuflenNum EQU $ - bufnum         
    HandlerNum DW ?                   
Filenum DB "num.txt",0 
 
;OTHER SIMBOLS
Buf6 DB "other simbol:", 13,10,"$"
    Buflen6 EQU $ - BUF6           
    Handler6 DW ?                   
Filename6 DB "other.txt",0  
 
 
exit:      ; exit
int 20h
end start 
code_seg ends
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.01.2018, 19:00
Ответы с готовыми решениями:

Запись строки с клавиатуры в переменную
Есть такой(для примера) код: org 7c00h ;установка видео режима mov al, 3...

Запись в файл пяти строк, введенных с клавиатуры
напишите пожалуйста программу))я не силен в ассемблере так как изучал другой...

Определить, есть ли во введённой с клавиатуры последовательности чисел три одинаковых последовательных числа
Пожалуйста помогите написать программу. Задание: Определить, есть ли в...

Вывод на экран введённой строки символов
Всем доброй день, преподаватель дал задание: Пользователь вводит с клавиатуры...

Запись Переноса строки в файл
Столкнулся с такой проблемой, как в ассемблере записать в файл перенос строки?...

33
Hou
0 / 0 / 0
Регистрация: 25.01.2018
Сообщений: 15
25.01.2018, 19:29  [ТС] 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
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
code_seg segment
ASSUME CS:code_seg,DS:code_seg,ES:code_seg
org 100h
 
start: 
; create file
MOV AH, 3Ch ; CREATE создание файла
MOV CX, 0 ; 
MOV DX, OFFSET Filenumber
INT 21H 
Mov HandlerNum, AX 
 
numbr DB 30h ; counter счетчик для чисел
othr db 30h;      для других символов
 
cycle: ;цикл
vvod proc near   ;vvod simbol into AL 
    mov len,30h          ; 
        mov AH, 01h   ;ввод с клавиатуры
        int 21h 
        mov bl,0Dh  
        cmp bl,al      ; проверка: если нажата клавиша enter
      je exit            ; то выход
        mov bl,27
        cmp bl,al      ;проверка: если нажата клавиша esc
      je exit            ;то выход
 
; проверяем число или нет
        ; check1 0<=AL<=9
        mov DH, 30h  ; DH=0
        cmp AL, DH   ; AL<DH?
      jc other          ; other
        mov DH, 3Ah  ; DH=9+1ascii
        cmp AL, DH   ; AL<DH?
      jc number      ; it is number
      jc other
 
 
other: 
;count
add othr, 1
;здесь по аналогу с цифрами вставлю
jmp cycle  ;возвращаю в цикл
 
number:
;count счетчик, вдруг понадобится
add numbr, 31h  
 
bufnum db ' '  ; вроде как буфер
 
;
;   здесь должна быть запись из AL в буфер
;
 
mov  ah,40h        ; это вроде как запись в файл, но оно кидает в файл что-то непонятное
mov  bx,handlernum    
mov  cx,3        
lea dx,bufnum
int 21h
mov ah,3eh
mov bx,handlernum
int 21h
 
 
jmp cycle   ; возвращаем в цикл
 
 
 
 
 
;NUMBER    
 
    BuflenNum EQU $ - bufnum         
    HandlerNum DW ?                   
Filenum DB "num.txt",0 
 
;OTHER SIMBOLS
Buf6 DB "other simbol:", 13,10,"$"
    Buflen6 EQU $ - BUF6           
    Handler6 DW ?                   
Filename6 DB "other.txt",0  
 
 
exit:      ; exit
int 20h
end start 
code_seg ends
0
ФедосеевПавел
Модератор
3657 / 2028 / 839
Регистрация: 01.02.2015
Сообщений: 6,753
25.01.2018, 20:26 3
Я, конечно, боюсь обидеть, но любопытство сильнее - ЭТО компилируется?

Добавлено через 7 минут
Так выглядит шаблон программы (структура)
Бесконечное повторение кода после команды IDIV

Кесарю - кесарево. Т.е. данные - к данным, код - к коду. Это не С/С++ с его адской смесью кода и данных.

Сортировка. Вы сумбурно пояснили критерий сортировки. Поэтому предлагаю модификацию сортировки "пузырьком". По ссылке пояснения и ссылки на необычные примеры
Программа для сортировки любого массива

Добейтесь компиляции, ввода, сортировки вывода на экран. Потом можно добавлять работу с файлом.
1
Hou
0 / 0 / 0
Регистрация: 25.01.2018
Сообщений: 15
28.01.2018, 00:49  [ТС] 4
это компилируется. нам не объясняли, где данные должны быть. мы их и в начале и в конце писали
у меня в конечной программе еще сложнее сортировка, потому что надо рассортировать не только цифры-не цифры, но и англ заглавные и строчные и русские заглавные и строчные
мне важен именно механизм, как из задать буфер "бесконечный"(я сколько гуглю, не могу понять), из AL закинуть туда символ, а в конце, когда будет нажата esc или enter(эти вещи уже прописаны в моем коде), выйти из цикла и все шесть буферов закинуть в разные файлы
ну и таблицу составить где рядом с именем файла написано число символов
0
ФедосеевПавел
Модератор
3657 / 2028 / 839
Регистрация: 01.02.2015
Сообщений: 6,753
28.01.2018, 09:04 5
Хорошо. Теперь взаимное расположение данных и кода известно - можно и перекомпоновать исходник.

Бесконечный буфер задать невозможно, т.к. адресация (индексные регистры) всего по 16 бит, т.е. адресуют 64КиБайт.
Для буфера ввода с клавиатуры выделите (зарезервируйте) какой-нибудь участок памяти размером в несколько КиБайт, да и дело с концом. Если иное не обговорено в условии задачи.
Assembler
KeyBuffer db 10*1024 dup(?)
По поводу сортировки. Что о ней в задании. Ведь раскассовать символы на 6 групп (буферов) можно на этапе ввода. Можно раскассовывать после ввода на 6 буферов. А можно не добавляя новых буферов отсортировать в исходном, а потом оперировать участками в этом отсортированном буфере.

Сама сортировка не так и страшна - все эти буквы в кодовой таблице идут по порядку (цифры, знаки препинания, заглавные английские, русские, строчные). Если вам знаком C++ сделайте эксперимент - встроенными средствами отсортируйте строку и выведите результат. Буквы будут отсортированы именно по нужному критерию. Останется только выделить диапазоны каждой группы.

И вообще - первичен алгоритм. Я бы отладил алгоритм на C/C++, а потом перенёс его на ассемблер. Для сложных случаев всегда поступаю именно так - тому подтверждение:
Сортировка Шелла
Сортировка "пузырьком"
Заполнить квадратную матрицу по спирали

Добавлено через 28 минут
Я предлагаю решать задачу поэтапно.
1. Ввод с клавиатуры.
2. Потом добавить сортировку или распределение - смотря, что требуется по условию.
3. Совсем потом - добавить вывод в файлы.
1
Hou
0 / 0 / 0
Регистрация: 25.01.2018
Сообщений: 15
28.01.2018, 09:45  [ТС] 6
Про сортировку не сказано, на каком этапе делать. я решила после ввода по всем ascii-кодам проверить, и потом кинуть на метку с обработкой символа
Если вы заметили, и ввод и сортировка уже присутствуют
0
ФедосеевПавел
Модератор
3657 / 2028 / 839
Регистрация: 01.02.2015
Сообщений: 6,753
28.01.2018, 13:14 7
Я понял, что исходники из начала темы работать не будут и даже читать их не стал.

Это всё лирика. Вы - умеете работать, поэтому приводите итоговый на данный момент исходник. Попробуем его разобрать.
А также уточните о какой сортировке идёт речь (критерии), т.к. символы могут быть не только цифрами, кириллицей или латиницей - что делать со знаками препинания, символами псевдографики и прочими.

Добавлено через 2 минуты
Также интересно, требуется ли сохранять порядок символов. Т.е. из строки
"814р7л3"
в файл с цифрами записать
"81473" или "13478"?

Добавлено через 2 часа 5 минут
Ввод символов без какой-либо обработки
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
code_seg        segment
        ASSUME CS:code_seg,DS:code_seg,ES:code_seg
        org 100h
 
start:
        ;ввод символов
        mov     cx,     MAX_CHARS       ;ограничим количество символов
        lea     di,     [KeyBuffer]     ;адрес буфера
        mov     [CountChars],   0       ;пока нет символов в буфере
        @@InCHars:
                ;ввод символа
                mov     ah,     01h
                int     21h
                ;проверки, на нажатие управляющих клавиш
                cmp     al,     kbENTER
                je      @@InCharsBreak
                cmp     al,     kbESC
                je      @@InCharsBreak
                ;если это не управляющая клавиша, то
 
                mov     [di],   al      ; - сохранить её в буфере
                inc     [CountChars]    ; - увеличить количество символов в буфере
                inc     di              ; - перейти к следующему элементу буфера
        loop    @@InChars
        @@InCharsBreak:
 
        ;обработка символов
 
        ;сохранение результатов в файлы
 
        ;пока тестовый вывод введённого буфера на экран
        mov     ah,     40h
        mov     bx,     1
        mov     cx,     [CountChars]
        lea     dx,     [KeyBuffer]
        int     21h
 
 
 
@@exit:
        ;завершение программы
        int     20h
 
;-----------------------------------------------------------
; подпрограммы
;-----------------------------------------------------------
 
 
;-----------------------------------------------------------
; переменные и константы
;-----------------------------------------------------------
kbENTER         equ     0Dh     ;код клавиши ENTER
kbESC           equ     1Bh     ;код клавиши ESC
 
MAX_CHARS       equ     10*1024 ;максимальный размер буфера клавиатуры
 
CountNumber     dw      ?       ;количество символов "цифры"
CountBigCyr     dw      ?       ;количество символов "заглавные кириллические"
CountSmallCyr   dw      ?       ;количество символов "строчные кириллические"
CountBigLatin   dw      ?       ;количество символов "заглавные латинские"
CountSmallLatin dw      ?       ;количество символов "строчные латинские"
CountOther      dw      ?       ;количество остальных символов
 
CountChars      dw      ?       ;количество символов в буфере
 
;в самом конце располагаем буфер для чтения символов с клавиатуры
KeyBuffer       label   byte
 
code_seg        ends
 
        end     start
1
Hou
0 / 0 / 0
Регистрация: 25.01.2018
Сообщений: 15
29.01.2018, 09:47  [ТС] 8
Исходное задание:
Рассортировать в разные файлы введенную с клавиатуры строку.
Вывести в отдельные файлы:
1 Большие латинские буквы
2 Маленькие латинские буквы
3 Большие русские буквы
4 Маленькие русские буквы
5 Цифры
6 Прочие символы
Подсчитать количество символов в каждом файле и вывести на экран таблицу:
1 Большие латинские буквы - имя файла - кол-во символов
2 Маленькие латинские буквы - имя файла - кол-во символов
3 Большие русские буквы - имя файла - кол-во символов
4 Маленькие русские буквы - имя файла - кол-во символов
5 Цифры - имя файла - кол-во символов
6 Прочие символы - имя файла - кол-во символов

Сортирую через ascii-коды. (добавила "space" -> введите ещё раз, но "tab" и прочие остались нетронуты и идут в символы)
Добавила ваш ввод в буфер и вывод на экран. Цифры пишутся поверх того, что уже было на экране. Надо будет перед выводом таблицы замутить клир скрин.
А также, наверное, стоит добавить ошибку, если в буфере закончилось место или при создании файла места не хватает
Поставила в конец данные, как Вы и просили.
Код сейчас выглядит так (отлично компилируется!):
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
code_seg segment
ASSUME CS:code_seg,DS:code_seg,ES:code_seg
 
org 100h
 
start:      
 
;CREATE FILES
MOV AH, 3Ch ; BIG EN
MOV CX, 0 ; 
MOV DX, OFFSET FileBE
INT 21H 
Mov handleBE, AX 
 
MOV AH, 3Ch ; BIG RU
MOV CX, 0 ; 
MOV DX, OFFSET FileBR 
INT 21H 
Mov HandleBR, AX  
 
MOV AH, 3Ch ; SMALL EN
MOV CX, 0 ; 
MOV DX, OFFSET FileSE
INT 21H 
Mov HandleSE, AX 
 
MOV AH, 3Ch ; SMALL RU
MOV CX, 0 ; 
MOV DX, OFFSET FileSR
INT 21H 
Mov HandleSR, AX 
 
MOV AH, 3Ch ; NUMBER
MOV CX, 0 ; 
MOV DX, OFFSET FileNUM
INT 21H 
Mov HandleNUM, AX  
 
MOV AH, 3Ch ; OTHER
MOV CX, 0 ; 
MOV DX, OFFSET FileOTHR
INT 21H 
Mov HandleOTHR, AX
  
 
mov     cx,     MAX_CHARS       
lea     di,     [KeyBuffer]     
mov     [CountChars],   0  
 
 
;START PROGRAM
@@cycle: 
vvod proc near   ;vvod simbol into AL 
                
        mov    AH,  01h   ;if "ENTER" and "ESC"  -> exit
        int    21h 
        mov    bl,  0Dh
        cmp    bl,  al      
        je   @@exit  
        mov    bl,  27
        cmp    bl,  al      
        je   @@exit 
        mov    bl,  020h   ;if "SPACE" -> enter simbol again
        cmp    bl,  al      
        je   @@cycle
        ; check1 0<=AL<=9
        mov    DH,  30h  ; DH=0
        cmp    AL,  DH   ; AL<DH?
        jc   @@other     ; other
        mov    DH,  3Ah  ; DH=9+1ascii
        cmp    AL,  DH   ; AL<DH?
        jc   @@number      ; it is number
             
        mov    DH,  41h  ;Big eng
        cmp    AL,  DH
        jc   @@other
        mov    DH,  5Ah
        cmp    AL,  DH
        jc   @@BigEng 
      
        mov    DH,  61h   ;Lit eng
        cmp    AL,  DH
        jc   @@other
        mov    DH,  7Ah
        cmp    AL,  DH
        jc   @@smallEng 
      
        mov    DH,  80h    ;Big ru
        cmp    AL,  DH
        jc   @@other
        mov    DH,  9fh
        cmp    AL,  DH
        jc   @@BigRu
      
        mov    DH,  0A0h    ;lit ru (part1)
        cmp    AL,  DH
        jc   @@other
        mov    DH,  0AFh
        cmp    AL,  DH
        jc   @@smallRu
      
        mov    DH,  0E0h    ;Lit ru (part2) 
        cmp    AL,  DH
        jc   @@other
        mov    DH,  0EFh
        cmp    AL,   DH
        jc   @@smallRu
      
        mov    DH,  0F0h  ; р
        cmp    AL,   DH
        jc   @@BigRu
        
        mov    DH,  0F1h  ; с
        cmp    AL,   DH
        jc   @@smallRu
        mov    DH,  0F2h
        cmp    AL,  DH
        jc   @@other
 
 
@@other: 
jmp @@cycle
 
@@number:
 
mov     [di],   al      
inc     [CountChars]    
inc     di   
 
jmp @@cycle
 
@@smallRu:
jmp @@cycle 
 
@@smallEng:  
jmp @@cycle 
 
@@BigRu:
jmp @@cycle
 
@@BigEng:  
jmp @@cycle     
 
vvod endp
 
jmp @@cycle  
 
 
@@exit:
        
        mov     ah,     40h
        mov     bx,     1
        mov     cx,     [CountChars]
        lea     dx,     [KeyBuffer]
        int     21h
        
int 20h
 
 
;DATA
MAX_CHARS       equ     10*1024
 
CountNumber     dw      ?      
CountBigCyr     dw      ?      
CountSmallCyr   dw      ?      
CountBigLatin   dw      ?      
CountSmallLatin dw      ?     
CountOther      dw      ?     
 
CountChars      dw      ?       
 
;BIG ENG FILE
HandleBE DW ?                   
FileBE DB "bigen.txt",0 
 
;BIG RU FILE
HandleBR DW ?                   
FileBR DB "bigru.txt",0 
  
;small ENG FILE
HandleSE DW ?                   
FileSE DB "smallen.txt",0 
 
;small RU FILE           
HandleSR DW ?                   
FileSR DB "smallru.txt",0 
 
;NUMBER FILE              
HandleNUM DW ?                   
FileNUM DB "num.txt",0 
   
;OTHER FILE           
HandleOTHR DW ?                   
FileOTHR DB "other.txt",0  
 
KeyBuffer   label   byte
 
end start 
code_seg ends
0
ФедосеевПавел
30.01.2018, 01:44
  #9

Не по теме:

Немного освобожусь - почитаю

0
ФедосеевПавел
Модератор
3657 / 2028 / 839
Регистрация: 01.02.2015
Сообщений: 6,753
31.01.2018, 18:40 10
Излишние копирования значений в регистры
Assembler
57
58
59
60
61
62
63
64
65
66
67
68
        mov    bl,  0Dh
        cmp    bl,  al      
        je   @@exit  
        mov    bl,  27
        cmp    bl,  al      
        je   @@exit 
        mov    bl,  020h   ;if "SPACE" -> enter simbol again
        cmp    bl,  al      
        je   @@cycle
        ; check1 0<=AL<=9
        mov    DH,  30h  ; DH=0
        cmp    AL,  DH   ; AL<DH?
Можно гораздо проще - сразу сравнивать регистр с константой
Assembler
57
58
        cmp    al,  0Dh
        je   @@exit
Добавлено через 5 минут
Сами сравнения, вернее переходы по результатам сравнения
Assembler
67
68
69
        mov    DH,  30h  ; DH=0
        cmp    AL,  DH   ; AL<DH?
        jc   @@other     ; other
Заменить бы на
Assembler
67
68
        cmp    AL,  "0"  ; AL<"0"?
        jb   @@other     ; other
Здесь поясняется применимость команд условных переходов
http://www.cyberforum.ru/post5356780.html

Добавлено через 9 минут
Знаете, можно организовать запись в файлы, записывая по одному символу в соответствующий файл.
Т.е.
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.............
        cmp    AL,  "0"  ; AL<"0"?
        jb   @@other     ; other
..............
 
@@other:
        mov bx, HandleOTHR
        jmp @@WriteToFile
.............
@@WriteToFile:
        mov ah, функция записи в файл
        ;mov bx, описатель файла уже в bx
        mov cx, 1 ;записать один символ
        mov dx, ??????; т.к. в условии сначала вводится строка, а затем она обрабатывается.
        int 21h
 
        jmp @@cycle
Добавлено через 4 минуты
*******************************
Мне кажется, что ввод и одновременная обработка символов - не соответствует условию задания
Цитата Сообщение от Hou Посмотреть сообщение
Исходное задание:
Рассортировать в разные файлы введенную с клавиатуры строку.
Вывести в отдельные файлы:
Т.е. сначала строка вводится, а затем обрабатывается.

В условии нет указания способа ввода. Т.е. не обязательно организовывать цикл ввода - можно обратиться к ОС, чтобы она собственными средствами ввела строку. Или всё же есть указания или "традиции" на этот счёт?

Добавлено через 6 минут
**********************
Всё вышеприведённое мною - так, мысли вслух.
У меня вопросы:
1. Есть указания или "традиции" (=изученные способы) ввода строки?
Можно ввести строку (длиной до 255 символов)
Assembler
1
2
3
4
5
kbdBuf db 255, ?, 255 dup(?)
....
mov ah, 0Ah
lea dx, kbdBuf
int 21h
2. Если нет указаний - допустимо ли записывать в файлы по одному символу по мере обработки? Т.е. без сортировки?
0
Hou
0 / 0 / 0
Регистрация: 25.01.2018
Сообщений: 15
01.02.2018, 19:18  [ТС] 11
Убрала излишнее копирование. Спасибо, я не заметила.
Я думаю, что лучше все же работать целиком со строкой, а не отдельно каждый символ обрабатывать, но тогда нужно обработку другую делать.

Добавлено через 17 минут
Изученный способ ввода я представила, но если есть способы проще, было бы здорово использовать их.
Сортировку 1490 -> 0149 делать не нужно, если вы об этом.
Что можно по таблицам найти? Я искала в гугле, но мне попадались только в TASM работы, я с этой средой не знакома. Попробую еще раз прошерстить учебник.
0
ФедосеевПавел
Модератор
3657 / 2028 / 839
Регистрация: 01.02.2015
Сообщений: 6,753
01.02.2018, 19:36 12
Немного не понял про таблицы.

Я предлагаю решать так
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
;ввод строки String
............
;открытие всех 6-ти файлов на запись
............
;обработка строки
lea si, [String]
mov cx, LengthString
 
@@For:
  mov al, [si]
  inc si
 
  cmp al, "0"
  jb @other
  cmp al, "9"
  jbe @digits
 
  cmp al, "A"
  jb @TestSE
  cmp al, "Z"
  jbe @BigLatin
@TestSE:
.................
 
  ;другие символы
@other:
  mov bx, HandleOTHR
  jmp @@WriteToFile
  ;цифры
@digits:
  mov bx, HandleNUM
  jmp @@WriteToFile
..................
 
@@WriteToFile:
@@WriteToFile:
        mov ah, функция записи в файл
        ;mov bx, описатель файла уже в bx
        mov cx, 1 ;записать один символ
        mov dx, si
        dec dx      ;т.к. si увеличилось на 1 сразу после чтения символа
        int 21h
 
loop @@For
0
ФедосеевПавел
Модератор
3657 / 2028 / 839
Регистрация: 01.02.2015
Сообщений: 6,753
03.02.2018, 13:38 13
Т.к. долго было бы набирать тестовые условия, то добавил макрос для проверки диапазона
Только запись в файлы
Т.к. кодировки кириллицы различны в DOS и Windows (cp866 или cp1251), то для запуска в DOSBox перекодируйте исходник в cp866.

для вывода размеров файлов на экран также воспользуйтесь циклом и функцией LSEEK (int 21h ah=42h). Вывод числовых значений посмотрите в закреплённой теме Ввод и вывод чисел в различных системах счисления там был и вариант для 32-разрядного числа.

Рекомендую выводить в цикле, получая названия файлов и их описателей из существующих массивов.
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
code_seg        segment
        ASSUME CS:code_seg,DS:code_seg,ES:code_seg
        org 100h
 
TestRange       macro   RangeLo, RangeHi, OkRegister, OkValue, OkLabel
        local   @@ElseLabel
        cmp     al,     RangeLo
        jb      @@ElseLabel
        cmp     al,     RangeHi
        ja      @@ElseLabel
        mov     OkRegister, OkValue
        jmp     OkLabel
@@ElseLabel:
endm
 
start:
        ;ввод символов
        mov     ah,     0Ah
        lea     dx,     [KeyBuffer]     ;адрес буфера
        int     21h
        mov     ah,     09h
        lea     dx,     [CrLf]
        int     21h
        ;открытие файлов на запись
        mov     cx,     6
        lea     di,     [FileNamesTable]
        lea     si,     [FileHandleTable]
        @@OpenFiles:
                push    cx
                mov     ah,     3Ch     ;открытие файла
                mov     dx,     [di]
                mov     cx,     0
                int     21h
                jnc     @@OkOpen
 
                mov     ah,     09h
                lea     dx,     [msgErrFileOpen]
                jmp     @@CloseFiles
        @@OkOpen:
                mov     [si],   ax      ;сохранение описателя
                pop     cx
                add     di,     2       ;перейти к следующему указателю на имя
                add     si,     2
        loop    @@OpenFiles
 
        ;обработка символов строки
        lea     si,     [String]
        mov     cl,     [RealLength]
        mov     ch,     0
        cld
        jcxz    @@ShowResult
        @@ForEachChar:
                push    cx
 
                lodsb
 
                TestRange       'A', 'Z', bx, 0*2, @@WriteToFile
                ;кириллица в кодировке cp866 разделена на несколько поддиапазонов
                TestRange       'А', 'Я', bx, 1*2, @@WriteToFile
                cmp     al,     'Ё'
                jne     @@TestSE
                mov     bx,     1*2
                jmp     @@WriteToFile
        @@TestSE:
                TestRange       'a', 'z', bx, 2*2, @@WriteToFile
                ;кириллица в кодировке cp866 разделена на несколько поддиапазонов
                TestRange       'а', 'п', bx, 3*2, @@WriteToFile
                TestRange       'р', 'я', bx, 3*2, @@WriteToFile
                cmp     al,     'ё'
                jne     @@TestNum
                mov     bx,     3*2
                jmp     @@WriteToFile
        @@TestNum:
                TestRange       '0', '9', bx, 4*2, @@WriteToFile
                mov     bx,     5*2
 
        ;сохранение результатов в файлы
        @@WriteToFile:
                lea     di,     [FileHandleTable]
                mov     ah,     40h
                mov     bx,     [bx+di]
                mov     cx,     1
                mov     dx,     si
                dec     dx
                int     21h
                pop     cx
 
        loop    @@ForEachChar
 
        ;вывод результатов
@@ShowResult:
 
 
@@CloseFiles:
        mov     cx,     6
        lea     si,     [FileHandleTable]
        @@Close:
                mov     ah,     3Eh
                mov     bx,     [si]
                int     21h
                add     si,     2
        loop    @@Close
 
@@exit:
        ;завершение программы
        int     20h
 
;-----------------------------------------------------------
; подпрограммы
;-----------------------------------------------------------
 
 
;-----------------------------------------------------------
; переменные и константы
;-----------------------------------------------------------
 
MAX_CHARS       equ     128     ;максимальный размер буфера клавиатуры
 
CountNumber     dw      ?       ;количество символов "цифры"
CountBigCyr     dw      ?       ;количество символов "заглавные кириллические"
CountSmallCyr   dw      ?       ;количество символов "строчные кириллические"
CountBigLatin   dw      ?       ;количество символов "заглавные латинские"
CountSmallLatin dw      ?       ;количество символов "строчные латинские"
CountOther      dw      ?       ;количество остальных символов
 
;инмена файлов
;BIG ENG FILE
FileBE          db "bigen.txt",0
;BIG RU FILE
FileBR          db "bigru.txt",0
;small ENG FILE
FileSE          db "smallen.txt",0
;small RU FILE
FileSR          db "smallru.txt",0
;NUMBER FILE
FileNUM         db "num.txt",0
;OTHER FILE
FileOTHR        db "other.txt",0
 
FileHandleTable label   word
HandleBE        dw      ?
HandleBR        dw      ?
HandleSE        dw      ?
HandleSR        dw      ?
HandleNum       dw      ?
HandleOthr      dw      ?
 
FileNamesTable  label   word
                dw      offset  FileBE
                dw      offset  FileBR
                dw      offset  FileSE
                dw      offset  FileSR
                dw      offset  FileNum
                dw      offset  FileOthr
 
msgErrFileOpen  db      'Error file open', '$'
CrLf            db      0Dh, 0Ah, '$'
 
;в самом конце располагаем буфер для чтения символов с клавиатуры
KeyBuffer       label   byte
MaxLength       db      MAX_CHARS
RealLength      db      ?
String          db      MAX_CHARS dup(?)
 
code_seg        ends
 
        end     start
Добавлено через 1 час 5 минут
Так, в окончательном виде
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
code_seg        segment
        ASSUME CS:code_seg,DS:code_seg,ES:code_seg
        org 100h
 
TestRange       macro   RangeLo, RangeHi, OkRegister, OkValue, OkLabel
        local   @@ElseLabel
        cmp     al,     RangeLo
        jb      @@ElseLabel
        cmp     al,     RangeHi
        ja      @@ElseLabel
        mov     OkRegister, OkValue
        jmp     OkLabel
@@ElseLabel:
endm
 
start:
        ;ввод символов
        mov     ah,     0Ah
        lea     dx,     [KeyBuffer]     ;адрес буфера
        int     21h
        mov     ah,     09h
        lea     dx,     [CrLf]
        int     21h
        ;открытие файлов на запись
        mov     cx,     6
        lea     di,     [FileNamesTable]
        lea     si,     [FileHandleTable]
        @@OpenFiles:
                push    cx
                mov     ah,     3Ch     ;открытие файла
                mov     dx,     [di]
                mov     cx,     0
                int     21h
                jnc     @@OkOpen
 
                mov     ah,     09h
                lea     dx,     [msgErrFileOpen]
                jmp     @@CloseFiles
        @@OkOpen:
                mov     [si],   ax      ;сохранение описателя
                pop     cx
                add     di,     2       ;перейти к следующему указателю на имя
                add     si,     2
        loop    @@OpenFiles
 
        ;обработка символов строки
        lea     si,     [String]
        mov     cl,     [RealLength]
        mov     ch,     0
        cld
        jcxz    @@ShowResult
        @@ForEachChar:
                push    cx
 
                lodsb
 
                TestRange       'A', 'Z', bx, 0*2, @@WriteToFile
                TestRange       'a', 'z', bx, 1*2, @@WriteToFile
                ;кириллица в кодировке cp866 разделена на несколько поддиапазонов
                TestRange       'А', 'Я', bx, 2*2, @@WriteToFile
                cmp     al,     'Ё'
                jne     @@TestSR
                mov     bx,     2*2
                jmp     @@WriteToFile
        @@TestSR:
                ;кириллица в кодировке cp866 разделена на несколько поддиапазонов
                TestRange       'а', 'п', bx, 3*2, @@WriteToFile
                TestRange       'р', 'я', bx, 3*2, @@WriteToFile
                cmp     al,     'ё'
                jne     @@TestNum
                mov     bx,     3*2
                jmp     @@WriteToFile
        @@TestNum:
                TestRange       '0', '9', bx, 4*2, @@WriteToFile
                mov     bx,     5*2
 
        ;сохранение результатов в файлы
        @@WriteToFile:
                lea     di,     [FileHandleTable]
                mov     ah,     40h
                mov     bx,     [bx+di]
                mov     cx,     1
                mov     dx,     si
                dec     dx
                int     21h
                pop     cx
 
        loop    @@ForEachChar
 
        ;вывод результатов
@@ShowResult:
        mov     cx,     6
        mov     si,     0
        @@ForEachGroup:
                mov     ah,     09h
                mov     dx,     ResultMsgTable[si]
                int     21h
 
                mov     dx,     FileNamesTable[si]
                call    WriteAsciiz
 
                mov     ah,     09h
                lea     dx,     [msgResultMedium]
                int     21h
 
                mov     bx,     FileHandleTable[si]
                call    FileSize
                call    ShowUInt32
 
                mov     ah,     09h
                lea     dx,     [CrLf]
                int     21h
 
                add     si,     2
        loop    @@ForEachGroup
 
@@CloseFiles:
        mov     cx,     6
        lea     si,     [FileHandleTable]
        @@Close:
                mov     ah,     3Eh
                mov     bx,     [si]
                int     21h
                add     si,     2
        loop    @@Close
 
@@exit:
        ;завершение программы
        int     20h
 
;-----------------------------------------------------------
; подпрограммы
;-----------------------------------------------------------
;размер открытого файла
;на входе:
;  bx - описатель файла
;на выходе:
;  dx:ax - размер файла
FileSize        proc
        ;push   ax
        push    bx
        push    cx
        ;push   dx
        push    si
        push    di
 
        mov     ax,     4202h
        ;mov    bx,     bx
        mov     cx,     0
        mov     dx,     0
        int     21h
        jc      @@fsError
        jmp     @@fsOk
@@fsError:
        mov     ax,     0
        mov     dx,     0
@@fsOk:
        pop     di
        pop     si
        ;pop    dx
        pop     cx
        pop     bx
        ;pop    ax
        ret
FileSize        endp
;Вывод на экран целого 32 разрядного беззнакового числа
;на входе:
;  dx:ax - целое 32 разрядное беззнаковое число
ShowUInt32      proc
LOCAL   temp:DWORD      ;переменная для сохранения частного от деления на 10
        push    ax
        push    bx
        push    cx
        push    dx
        push    si
        push    di
        ;сохранить значение числа во временной переменной
        mov     word ptr temp[0],       ax
        mov     word ptr temp[2],       dx
 
        mov     bx,     10      ;делитель
        mov     di,     0       ;количество цифр
@@NextDigit:
        mov     cx,     2       ;количество операций деления
        mov     si,     2       ;смещение делимого в переменной temp
        mov     dx,     0       ;остаток от предыдущего деления на 10
@@DivBy10:
        mov     ax,     word ptr temp[si]
        div     bx
        mov     word ptr temp[si],      ax
        sub     si,     2
        loop    @@DivBy10
        ;преобразование остатка от деления temp на 10 в символ цифры
        add     dl,     '0'
        push    dx              ;сохранение символа цифры в стеке
 
        inc     di              ;счётчик цифр увеличить на 1
 
        mov     ax,     word ptr temp[0]        ;остаток равен 0?
        or      ax,     word ptr temp[2]
        jnz     @@NextDigit                     ;нет - продолжить
 
        ;вывод цифр
        mov     cx,     di      ;количество выводимых символов
        mov     ah,     02h     ;функция вывода на экран для int 21h
@@ShowDigit:
        pop     dx              ;извлечение цифры из стека
        int     21h             ;вывод символа на экран
        loop    @@ShowDigit
 
        pop     di
        pop     si
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        ret
ShowUInt32      endp
;вывод строки, заканчивающеёся нулём (ASCIIZ)
;на входе:
;  ds:dx - адрес начала ASCIIZ строки
;на выходе:
; -
WriteAsciiz     proc
        push    ax
        push    bx
        push    cx
        push    dx
        push    si
        push    di
 
        mov     si,     dx
 
        mov     ah,     02h
        jmp     @@NextChar
        @@WriteChar:
                int     21h
        @@NextChar:
                mov     dl,     [si]
                inc     si
                or      dl,     dl
        jnz     @@WriteChar
 
        pop     di
        pop     si
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        ret
WriteAsciiz     endp
 
;-----------------------------------------------------------
; переменные и константы
;-----------------------------------------------------------
 
MAX_CHARS       equ     128     ;максимальный размер буфера клавиатуры
 
CountBigLatin   dw      ?       ;количество символов "заглавные латинские"
CountSmallLatin dw      ?       ;количество символов "строчные латинские"
CountBigCyr     dw      ?       ;количество символов "заглавные кириллические"
CountSmallCyr   dw      ?       ;количество символов "строчные кириллические"
CountNumber     dw      ?       ;количество символов "цифры"
CountOther      dw      ?       ;количество остальных символов
 
;сообщения
msgResultBE     db      'Большие латинские буквы - ', '$'
msgResultSE     db      'Маленькие латинские буквы - ', '$'
msgResultBR     db      'Большие русские буквы - ', '$'
msgResultSR     db      'Маленькие русские буквы - ', '$'
msgResultNum    db      'Цифры - ', '$'
msgResultOthr   db      'Прочие символы - ', '$'
 
msgResultMedium db      ' - ', '$'
 
msgErrFileOpen  db      'Error file open', '$'
CrLf            db      0Dh, 0Ah, '$'
 
;имена файлов
FileBE          db "bigen.txt",0        ;BIG ENG FILE
FileSE          db "smallen.txt",0      ;small ENG FILE
FileBR          db "bigru.txt",0        ;BIG RU FILE
FileSR          db "smallru.txt",0      ;small RU FILE
FileNUM         db "num.txt",0          ;NUMBER FILE
FileOTHR        db "other.txt",0        ;OTHER FILE
 
;таблица описателей файлов
FileHandleTable label   word
HandleBE        dw      ?
HandleSE        dw      ?
HandleBR        dw      ?
HandleSR        dw      ?
HandleNum       dw      ?
HandleOthr      dw      ?
;таблица указателей на имена файлов
FileNamesTable  label   word
                dw      offset  FileBE
                dw      offset  FileSE
                dw      offset  FileBR
                dw      offset  FileSR
                dw      offset  FileNum
                dw      offset  FileOthr
;таблица указателей на строки вывода результата
ResultMsgTable  label   word
                dw      offset  msgResultBE
                dw      offset  msgResultSE
                dw      offset  msgResultBR
                dw      offset  msgResultSR
                dw      offset  msgResultNum
                dw      offset  msgResultOthr
 
;в самом конце располагаем буфер для чтения символов с клавиатуры
KeyBuffer       label   byte
MaxLength       db      MAX_CHARS
RealLength      db      ?
String          db      MAX_CHARS dup(?)
 
code_seg        ends
 
        end     start
0
Hou
0 / 0 / 0
Регистрация: 25.01.2018
Сообщений: 15
07.02.2018, 14:47  [ТС] 14
Для какой среды это написано? emu8086 не эмулирует совсем

Добавлено через 8 минут
Ещё вопрос: как это перекодировать? '80' - А или без кавычек?
0
ФедосеевПавел
Модератор
3657 / 2028 / 839
Регистрация: 01.02.2015
Сообщений: 6,753
07.02.2018, 19:07 15
Я думал, что вы работаете в DOSBox компилятором tasm. Для такого набора я и проверял компиляцию и работоспособность.

Видимо, emu8086 не поддерживает макросы. Значит придётся все условия переписать кодом с кучей меток.
Там смысл макроса - замена конструкции
C
1
2
3
4
5
6
7
8
9
if ((al>=RangeLo) && (al<=RangeHi))
{
  bx=OkValue;//номер диапазона к которому принадлежит символ al
  goto WriteToFile;
}
else
{
  проверить следующий диапазон
}
Добавлено через 1 минуту
Не понял вопрос
Цитата Сообщение от Hou Посмотреть сообщение
как это перекодировать? '80' - А или без кавычек?
Добавлено через 2 минуты

Не по теме:

Если не очень сложно, не пропадайте надолго - уже через сутки с трудом вспоминаю контекст.

0
Hou
0 / 0 / 0
Регистрация: 25.01.2018
Сообщений: 15
08.02.2018, 00:55  [ТС] 16
Извините :с
0
ФедосеевПавел
Модератор
3657 / 2028 / 839
Регистрация: 01.02.2015
Сообщений: 6,753
08.02.2018, 07:37 17
Не пойму, за что извиняться.

По поводу ошибки компиляции - нужно заменить макросы TestRange на аналогичный код и удалить описание макроса. Вы умеете программировать - поэтому ограничился советом.

По второму вопросу - не разобрался о чём речь. Если ещё актуально - уточняйте.
0
Hou
0 / 0 / 0
Регистрация: 25.01.2018
Сообщений: 15
08.02.2018, 09:14  [ТС] 18
Что такое макросы? Какой там аналогичный код должен быть?
Когда я кодировку меняю, как в итоге должно выглядеть: 'А', '80', просто 80? Я не знаю как перекодировать. Если с помощью клавиатуры, то там нет нужных букв в этой кодировке.
0
Uncle Remus
Заблокирован
08.02.2018, 12:21 19
Цитата Сообщение от Hou Посмотреть сообщение
Что такое макросы?
Электронный учебник http://www.cyberforum.ru/cgi-bin/latex.cgi?\rightarrow Глава 21. Макроязык
1
ФедосеевПавел
Модератор
3657 / 2028 / 839
Регистрация: 01.02.2015
Сообщений: 6,753
08.02.2018, 19:09 20
Hou, вы уже обратили внимание на малую полезную нагрузку строк в ассемблере. Чтобы это преодолеть разработчики компиляторов внедрили сущность "макрос", когда вместо одной строки исходного текста в итоговый код подставляются множество других строк.
Например, объявим макрос
Assembler
1
2
3
4
5
Summa macro a,b,Result
  mov ax, a
  add ax, b
  mov Result, ax
endm
И теперь, когда в исходном тексте программы встретится строка Summa cx, var1, dx при компиляции вместо неё будет подставлены строки
Assembler
1
2
3
  mov ax, cx
  add ax, var1
  mov dx, ax
Таким образом макрос подобен процедуре, но код будет не вызываться, а формироваться на месте заменяемой строки.

Так и мне было неинтересно 5 раз записывать проверки 5-ти диапазонов. Я сделал макрос, который раскрывается в код проверки диапазона и 5 раз вызвал его в исходнике - это гораздо лучше, чем 5 раз копировать подобные строки с опасностью что-то забыть изменить в очередной копии.

По поводу кодировки. Для русской кириллицы существует две распространённые кодировки (их много больше, но действующих сейчас осталось только две) - это cp866 и cp1251.
https://ru.wikipedia.org/wiki/CP866
https://ru.wikipedia.org/wiki/Windows-1251
Затрудняюсь сказать, какую использует emu8086, в котором вы исполняете код. Сделайте тестовую программку по выводу одного символа с кодом E0h - если на экране выведется символ "р", то у emu8086 кодировка cp866, если символ "а" - cp1251.
Программу я набирал исходя из cp866. Для смены кодировки перед компиляцией измените кодировку всего исходника - это наиболее простой вариант. Или же замените кириллические символы на их коды в cp866. К примеру
Assembler
1
cmp al, 'я'
замените на
Assembler
1
cmp al, 0EFh
1
08.02.2018, 19:09
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.02.2018, 19:09

Запись строки в файл и вывод на экран
Добрый день! По задаче нужно ввести строку с клавиатуры, записать ее в файл и...

Запись в файл из командной строки на ассемблере
Добрый день! Нужна помщь в решении задачи: программа должна записывать в файл...

MASM32: Удалить все нули из введённой строки символов
Помогите написать на ассемблере код программы, который будет удалять все нули...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru