Форум программистов, компьютерный форум, киберфорум
Наши страницы
Assembler, MASM, TASM
Войти
Регистрация
Восстановить пароль
 
ExzoTikFruiT
2 / 2 / 0
Регистрация: 25.12.2012
Сообщений: 57
1

Упрощение программы

27.12.2014, 13:59. Просмотров 300. Ответов 0
Метки нет (Все метки)

Добрый день. Дали задание максимально сократить программу с сохранением работоспособности.
Заранее спасибо
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
;Ввести два массива. В первом массиве найти количество четных элементов,
;во втором – количество нечетных. Если количество четных элементов первого
;массива больше количества нечетных элементов второго, удвоить
;положительные элементы первого массива, в противном случае удвоить
;отрицательные элементы второго массива."
model small
SZ equ 10        ; размер массива 1,2
.stack 256
.data
ar1 db SZ*2 dup (0)   ;память для массива 1
ar2 db SZ*2 dup (0)   ;память для массива 2
buf    db 7,10 Dup(?) ; допуск-ся ввод всего 5 символов, минус и 1 служебный
k1  db (0)          ; количество четных элементов первого массива
k2  db (0)          ; количество нечетных элементов второго массива
mes11 db 13,10,"Vvedite chislo massiva 1  $"
mes12 db 13,10,"Vvedite chislo massiva 2  $"
mes6 db 13,10, "Massiv N1 = $"
mes7 db 13,10, "Massiv N2 = $"
mes8 db 13,10, "Oshibka pri vvode! Povtorite vvod = $"
mes9 db 13,10, "Kolich chetnix elem-v massiva N1 = $"
mes10 db 13,10, "Kolich NEchetnix elem-v massiva N2 = $"
newl db 13,10,'$'   ; перевод на новую строку
.code
print macro ad     ; макро вывода строки ad на экран
    push ax
    push dx
    mov ah,9
    mov dx,offset ad
    int 21h
    pop dx
    pop ax
    endm
putc   macro a     ; макро вывода символа а на экран
    push ax
    push dx
    mov ah,2
    mov dl,a
    int 21h
    pop dx
    pop ax
    endm
;
inp5z proc near    ; ввод числа (слова) через буфер со знаком
    push cx
    push bx
    push si
    mov ah,0ah
    xor di,di
    mov dx,offset buf ; адрес буфера
    int 21h ; принимаем строку
; обрабатываем содержимое буфера
    xor cx,cx
    mov si,offset buf+2 ; берем адрес начала строки
    cmp byte ptr [si],"-" ; если первый символ минус
    jnz ii1
    mov di,1  ; устанавливаем флаг
    inc si    ; и пропускаем его
ii1:
    xor ax,ax
    mov bx,10  ; основание сc (10)
ii2:
    mov cl,[si] ; берем символ из буфера
    cmp cl,0dh  ; проверяем не последний ли он
    jz endin
    
; если символ не последний, то проверяем его на правильность
    cmp cl,'0'  ; если введен неверный символ <0
    jl er2
    cmp cl,'9'  ; если введен неверный символ >9
    ja er2
 
    sub cl,'0' ; делаем из символа число 
    mul bx     ; умножаем на 10
    jo er2     ; проверка на возможное переполнение
    jc er2
    add ax,cx  ; прибавляем к остальным
    test ax,8000h   ; число должно быть положительным ( у нас же модуль)
    jnz  er2  
    inc si     ; указатель на следующий символ
    jmp ii2     ; повторяем до символа 0dh в строке
 
er2:   ; если была ошибка, то выводим сообщение об этом и выходим
;   soob errv
    stc
    jmp ii3
 
; все символы из буфера обработаны число находится в ax
endin:
    cmp di,1 ; если установлен флаг знака, то
    jnz ii8
    neg ax   ; делаем число отрицательным
ii8:    clc
    jmp ii7
ii3: nop
ii7:    pop si
    pop bx
    pop cx
    ret
inp5z   endp
 
vivbz proc near    ; ПП вывода байта из al со знаком
    push bp
    push bx
    xor bp,bp   ; bp использ как признак отриц числа
    xor ah,ah
    test al,80h ; число отрицательное?
    jz v2       ; нет
    neg al      ; да, отриц - превращаем его в положительное
    inc bp      ; устанавливаем признак отрицатеьности в bp
v2: mov bl,10   ; делим на 10, чтобы перевести из дв в симв вид
    div bl
    cmp bp,1    ; число отрицательное?
    jnz v3      ; нет
    putc '-'    ; да - выводим на экран знак минус
v3: or ax,3030h ; превращаем двоичные числа в ASCII
    mov bx,ax   ; сохраняем ax в bx
    putc bl     ; выводим старшую часть числа на экран
    putc bh     ; выводим младшую часть числа на экран
    pop bx
    pop bp
    ret
vivbz   endp
 
outint proc near       ; вывод числа из ax  со знаком
    push cx
    push bx
; Проверяем число на знак.
   test    ax, ax
   jns     oi1
 
; Если оно отрицательное, выведем минус и оставим его модуль.
   mov  cx, ax
   mov     ah, 02h
   mov     dl, '-'
   int     21h
   mov  ax, cx
   neg     ax
; Количество цифр будем держать в CX.
oi1:  
    xor     cx, cx
    mov     bx, 10 ; основание сс. 10 для десятеричной и т.п.
oi2:
    xor     dx,dx
    div     bx
; Делим число на основание сс. В остатке получается последняя цифра.
; Сразу выводить её нельзя, поэтому сохраним её в стэке.
    push    dx
    inc     cx
; А с частным повторяем то же самое, отделяя от него очередную
; цифру справа, пока не останется ноль, что значит, что дальше
; слева только нули.
    test    ax, ax
    jnz     oi2
; Теперь приступим к выводу.
    mov     ah, 02h
oi3:
    pop     dx
; Извлекаем очередную цифру, переводим её в символ и выводим.
    add     dl, '0'
    int     21h
; Повторим ровно столько раз, сколько цифр насчитали.
    loop    oi3
    pop bx
    pop cx
    ret
outint endp 
 
; *****************************************************************
 
start:               ; точка входа в программу
    mov ax,@data ; инициализация DS
    mov ds,ax
    mov cx, SZ  ; инициализация счетчика цикла ввода в массив 1 
    mov bx,offset ar1 ; bx = адрес массива 1
lp21:   print mes11  ; приглашение к вводу очередного эл-та массива 1
    call inp5z ; ввод очередного числа
    jc olu1     ; если при вводе было нажато Esc? то на выход из цикла
    mov word ptr [bx],ax ; иначе - вводим число в массив 1
    test ax,1 ; число четное?
    jnz dt2   ; нечетное - продолжить ввод
    inc k1    ; четное - суммировать счетчик к1
dt1:    add bx,2      ; переход на адрес след эл-та массива 1
    loop lp21   ; цикл ввода в массив 1
    jmp vvvm2
olu1:   print mes8
    jmp lp21
vvvm2:  print mes6  ; сообщение о содержимом массива 1
    mov cx, SZ
    mov bx, offset ar1 ; в bx  адрес начала массива 1
    print newl   ; переход на новую строку
omas1:  mov ax, [bx] ; ax = текущий выводимый элемент массива 1
    call outint   ; вывод текущего элемента массива 1 на экран из ax
    putc ' '     ; вывод разделителя (пробел)
    add bx,2       ; инкремент на следующий элемент массива 1 
    loop omas1   ; цикл вывода массива 1 на экран
;
vvv2:   mov cx,SZ    ; инициализация счетчика цикла ввода в массив 2ве1
    mov bx,offset ar2 ;bx = адрес массива 2
lp22:   print mes12  ; приглашение к вводу очередного эл-та массива 2
    call inp5z  ; ввод очередного числа
    jc olu2      ; если при вводе было нажато Esc? то на выход из цикла
    mov word ptr [bx],ax ; иначе - вводим число в массив 2
    test ax,1 ; число четное?
    jz dt1   ; четное - продолжить ввод
    inc k2    ; нечетное - суммировать счетчик к2
;
dt2:    add bx,2       ; переход на адрес след эл-та массива 2
    loop lp22    ; цикл ввода в массив 2
    jmp xx2
olu2:   print mes8
    jmp lp22
xx2:    print mes7   ; сообщение о выводе массива 2
    mov cx, SZ
    mov bx, offset ar2 ;bx = адрес массива 2
    print newl   ; переход на новую строку
omas2:  mov ax, [bx] ; ax = текущий выводимый элемент массива 2
    call outint   ; вывод текущего элемента массива 2 на экран из ax
    putc ' '     ; вывод разделителя (пробел)
    add bx,2       ; инкремент на следующий элемент массива 1
    loop omas2   ; цикл вывода массива 1 на экран
zapo:   nop
    nop
    nop          ; nop  для отладки
    nop
; вывод k1
    print mes9
    mov al,k1
    call vivbz
;
; вывод k2
    print mes10
    mov al,k2
    call vivbz
;
;Если количество четных элементов первого
;массива больше количества нечетных элементов второго, удвоить
;положительные элементы первого массива, в противном случае удвоить
;отрицательные элементы второго массива.
    mov al,k1
    cmp al,k2
    jz vivs   ; если равны, то оставляем массивы как есть
    ja udvp1 ;удвоить (+) элементы первого массива
udvm2: ;удвоить (-) элементы второго массива
    mov bx,offset ar2   ; из массива №2
    mov cx,SZ
aa2:    mov ax,[bx]
    test ax,8000h
    jz nxt1     ; если полож,  ТО цикл ДАЛЬШЕ
    sal ax,1    ; умножаем на 2 сдвигом влево
    mov [bx],ax ; и заменяем в массиве
nxt1:   add bx,2
    loop aa2
    jmp vivs
udvp1:  mov bx,offset ar1   ; из массива №1
    mov cx,SZ
aa3:    mov ax,[bx]
    test ax,8000h
    jnz nxt2     ; если отриц,  ТО цикл ДАЛЬШЕ
    sal ax,1     ; умножаем на 2 сдвигом влево
    mov [bx],ax ; и заменяем в массиве
nxt2:   add bx,2
    loop aa3
;    Вывод на экран 1-го массива
;   
vivs:   mov bx, offset ar1   ; вывод на экран массива №1
    mov cx,SZ
    print mes6
    print newl    ; выводим содержимое массива 1
vmas1:  mov ax,[bx]
    call outint
    putc ' '
    add bx,2
    loop vmas1    ; цикл вывода массива 1
;
    mov bx, offset ar2   ; вывод на экран массива №2
    mov cx,SZ
    print mes7
    print newl    ; выводим содержимое массива 1
vmas2:  mov ax,[bx]
    call outint
    putc ' '
    add bx,2
    loop vmas2    ; цикл вывода массива 2
;
vixx:   mov ax, 0     ; ожидание нажатия любой клавиши
    int 16h
    mov ax, 4c00h
    int 21h       ; выход из программы
    end start
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.12.2014, 13:59
Ответы с готовыми решениями:

Упрощение программы
Можно ли как-нибудь упростить эту программу? #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; int...

Упрощение программы
Program ads; Var f:text; i,j,k,p,n,s:integer; Begin assign(f,'zvezda.txt'); rewrite(f); p:=9;...

Упрощение программы
Программа написана крайне сложно, если можно, то сделайте максимально просто её. Время считает...

Упрощение кода программы
Здравствуйте уважаемые форумчане! Решил начать изучать язык Си++, начал с простого также как и при...

Упрощение программы посредством цикла
Есть текст: procedure TForm1.RadioGroup1Click(Sender: TObject); begin if...

0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.12.2014, 13:59

Упрощение программы с элементами одномерного массива
Вот я написал программу, которая вводит последовательно 20 чисел в одномерный масси, нашел среднее...

Упрощение процесса создания сложной программы
Здравствуйте! Подскажите пожалуйста, как Вы поступаете, когда алгоритм разрабатываемого приложения...

Упрощение
На форме есть 33 кнопки , у всех примерно одна и таже процедура нажатия,которая вполне огромная...


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

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

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