Переделать прогу

Низкоуровневое программирование портов, микроконтроллеров и т.д.

Модератор: Andy

Ответить
Аватара пользователя
M@X
Сообщения: 2
Зарегистрирован: 06 дек 2006, 14:51

Люди, вообщем есть код. Задача проги найти все четырехзначные числа у которых сумма первых двух чисел равна сумме вторых двух и вывести их в файл.

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


MODEL TINY
.486
.CODE
assume cs:@code,ds:@code,es:@code,ss:@code
org 100h

begin:
mov ah,09h
mov dx, offset a
int 21h
mov fnd,ax
mov ah,40h
mov bx,fnd
mov cx,2
mov dx,offset enter
int 21h

mov ah,2h
mov dl,0ah
int 21h


mov ah,3ch ;Создание файла
mov cx,0 ;Для записи и чтения
mov dx,offset fn
mov bx,fnd
int 21h

mov word ptr count,0

mov eax,0
mov ebx,0
mov ecx,0
mov edx,0
mov esi,0
mov edi,0

jmp s5

s1:


inc eax
jmp s5

s2:
inc ebx
jmp s5

s3:
inc ecx
jmp s5

s4:
inc edx
jmp s5

s5:
xor esi,esi
xor edi,edi

add esi,eax
add esi,ebx
add edi,ecx
add edi,edx

cmp esi,edi
jz s7

n1:
cmp edx,9
jz n2

jmp s4

n2:
mov edx,0
cmp ecx,9
jz n3

jmp s3

n3:
mov ecx,0
cmp ebx,9
jz n4

jmp s2

n4:
mov ebx,0
cmp eax,9
jz exit

jmp s1

s7:

inc count
push eax
push ebx
push ecx
push edx

call print_n pascal,eax,word ptr 0,word ptr 1,word ptr 1,word ptr 0,word ptr 0
call print_n pascal,ebx,word ptr 0,word ptr 1,word ptr 1,word ptr 0,word ptr 0
call print_n pascal,ecx,word ptr 0,word ptr 1,word ptr 1,word ptr 0,word ptr 0
call print_n pascal,edx,word ptr 0,word ptr 1,word ptr 1,word ptr 0,word ptr 0


call print_n pascal,eax,word ptr 0,word ptr 2,fnd,word ptr 0,word ptr 1
call print_n pascal,ebx,word ptr 0,word ptr 2,fnd,word ptr 0,word ptr 1
call print_n pascal,ecx,word ptr 0,word ptr 2,fnd,word ptr 0,word ptr 1
call print_n pascal,edx,word ptr 0,word ptr 2,fnd,word ptr 0,word ptr 1

mov ah,40h
mov bx,fnd
mov cx,1
mov dx,offset space
int 21h


mov ah,2h
mov dl,32
int 21h

pop edx
pop ecx
pop ebx
pop eax
jmp n1

exit:

mov fnd,ax
mov ah,40h
mov bx,fnd
mov cx,2
mov dx,offset ent
int 21h

mov ah,2h
mov dl,0ah
int 21h

mov ah,09h
mov dx, offset q
int 21h


call print_n pascal,word ptr count,word ptr 0,word ptr 1,word ptr 1,word ptr 0,word ptr 0
mov ah,4ch
int 21h

print_n proc near ;Процедура вывода десятичного числа на экран и в файл
locals @@
arg beg,zero,f_handle,pp0,num_off:word,numb:dword=arg_size

;Аргументы процедуры:
;numb: число(dword)
;num_off: смещение строки, где содержится число(word)
;pp0: 0-не печатать, 1-на экран, 2-в файл(word)
;f_handle: дескриптор файла(word)
;zero: 0-не печатать ведущие нули(word)
;beg: отступ в знаках от начала печатаемого числа(<=9)(word)

push bp
mov bp,sp
push eax
push ebx
push cx
push edx
push si

mov cx,10 ;Max длина выводимого числа
mov si,num_off
push cx

@p:
mov byte ptr [si],'0' ;Заполняем символами '0'
inc si
loop @p
pop cx
mov eax,numb ;Представляемое число
mov si,num_off ;Адрес результата для печати
add si,9
mov ebx,10 ;Делитель для выделения цифры

@@pr:
mov edx,0
div ebx
add dl,'0' ;Переводим символ в цифру
mov byte ptr [si],dl
or eax,eax ;eax=0?
jz short @@pr2
dec si
loop @@pr

@@pr2: ;В si фдрес первой ведущей ненулевой цифры
cmp pp0,0 ;Признак печати=0? Да-
je @@e6 ;Выход без печати
mov ah,40h ;Нет-печать числа

mov cx,10 ;Max длина числа
mov dx,offset num_off
mov bx,1 ;Дескриптор экрана
cmp pp0,2
je @@e1
jmp short @@e2

@@e1:
mov bx,f_handle ;Дескриптор файла
@@e2:
cmp zero,0
jne short @@e3
add cx,dx ;Помещаем в cx адрес первой ненулевой цифры
sub cx,si
mov dx,si
jmp short @@e4

@@e3:
sub cx,beg ;Ведущие нули
add dx,beg

@@e4:
int 21h

@@e6:
pop si
pop edx
pop cx
pop ebx
pop eax
mov sp,bp ;Восстанавливаем указатель стека к моменту выхода
pop bp
ret arg_size

print_n endp
a db 'Програма находящяя все четыятичные числа, у корехзначные десторых сумма первых двух цифр совпадает с суммой вторых двух.','$'
enter db ' '
q db 'Число совпадений равно ','$'
space db ' '
ent db '', '$'
fn db 'Kursovik.txt',0
fnd dw ?
count dw ?
end begin
Аватара пользователя
somewhere
Сообщения: 1858
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

Мддаааа.... Механизм ветвлений так хорошо закручен, что желания читать такую прогу у меня пропало. Переделать не возьмусь, а с алгоритмом помогу:

Для этого понадобится:

1. Процедура перевода числа из AX в десятичное представление. Причем для 4-х значного числа.
2. Процедура перевода числа из AX в десятичное представление с выводом на экран (или файл).
3. Ну и собственно сам цикл перебора чисел начиная с 1000 до 5000 с проверкой.

1. -----------------

Код: Выделить всё

GetNumberDigits proc near  ; в AX число, в DI - адрес, куда будут записываться числа.
pusha
mov bx, 10
mov cx, 4
add di, 3

@gnum:
xor dx,dx
div bx
mov [di], dl
dec di
loop @gnum
popa ; :-) вот так вот команда называется
ret
GetNumberDigits endp
2. -----------------

Код: Выделить всё

WriteNumber proc near ; в AX - число
pusha
mov bx,10
xor cx,cx

@wnum_1:
xor dx,dx
div bx
push dx
inc cx
or ax,ax
jnz @wnum_1

@wnum_2:
pop dx
add dl,30h
mov ah,2
int 21h
loop @wnum_2 
popa
ret
WriteNumber endp
3. --------------

Код: Выделить всё

push cs
pop ds
mov ax, 1000 ; начальное число
xor cx, cx ; кол-во полиндромов

@cycle:

mov di, offset Digits
call GetNumberDigits
mov bx, word ptr [di]
mov dx, word ptr [di+2]
add bl, bh
add dl, dh
cmp dl, bl
jnz @not_polindrom

call WriteNumber
inc cx

@not_polindrom:
inc ax
cmp ax, 5001
jnz @cycle

mov ax, cx
call WriteNumber    ;  вывести число полиндромов
...
...
Digits dd 0  ; здесь массив из цифр числа
Ответить