Консультация № 185191
16.01.2012, 18:13
52.33 руб.
0 9 1
Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос:
Вычислить функцию заданную в виде:
y(x) = а , если 1 < x <= 5
y(x) = b , если 5 < x <= 10
где а и в - элементы массивов А(I), В(I), стоящие в третьей позиции после сортировки в порядке возрастания. онсоль
Сортировку массива в порядке возрастания оформить в виде подпрограммы. I = 1,2,..,10.

Код желательно писать в расчёте на его компиляцию FASM.
Программа для консоли Windows. Вывод результата в существующую консоль.

Обсуждение

давно
Посетитель
7438
7205
16.01.2012, 18:24
общий
Адресаты:
Массивы, так понял, задаются в коде программы?
Если никто раньше не сделает, то вечером отвечу...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Мастер-Эксперт
425
4118
16.01.2012, 18:27
общий
Адресаты:
Да, массив прямо в коде программы. Спасибо.
Можно начинать делать прямо сейчас, меня это нисколько не расстроит.
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
давно
Посетитель
7438
7205
16.01.2012, 18:30
общий
16.01.2012, 18:31
Адресаты:
Да, данные - dword, word, byte ?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Мастер-Эксперт
425
4118
16.01.2012, 18:34
общий
Адресаты:
Тип данных - на Ваше усмотрение. Это непринципиально.
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
давно
Посетитель
7438
7205
17.01.2012, 05:23
общий
это ответ
Здравствуйте, sir Henry!
Вот программа.
Данные заданы в коде, Х вводится.

[code h=207]format PE console
include 'win32a.inc'
entry start

section '.data' data readable writeable
A dd 4,-4,-82,100,29,2,23,5,10,1
B dd 14,5,34,2,10,-5,0,20,12,7
X dd 6
sA db "A = ",0
sB db "B = ",0
sF db "F(%d) = %c = %d",13,10,0
lf db 13,10,0
sFormat db "%d ",0
sAfter db "After sorting",13,10,0
sEnter db "Enter X: ",0
sOutOfRange db "X outside the interval (1,10]",13,10,0
TableNumErrors dd sNumError, sNumOverflow
sNumError db "Number format error",13,10,0
sNumOverflow db "Number overflow error",13,10,0

section '.code' code readable executable

start:
call Main
invoke ExitProcess,0

;вывод в консоль строки
proc StdOut uses ebx, string
invoke lstrlen, [string] ;длина строки
mov ebx, eax ;в ebx
invoke GetStdHandle,STD_OUTPUT_HANDLE ;получим в eax handle консоли
push eax ;выделим в стеке слово
mov ecx,esp ;адрес слова в ecx
;пишем в консоль c eax=handle строку string длины ebx.
;Длина записанной строки будет в буфере, адрес которого в ecx
invoke WriteFile,eax,[string],ebx,ecx,0
pop eax
ret
endp

;ввод с консоли строки
proc StdIn string, len
invoke GetStdHandle,STD_INPUT_HANDLE ;получим в eax handle консоли
push eax
mov ecx, esp
invoke ReadConsole,eax,[string],[len],ecx,0
pop eax
ret
endp

;вывод массива чисел Array, количеством count с заголовком sName
proc Print uses esi, sName, Array, count
locals
buf db 16 dup (?) ;буфер для преобразования числа в строку
endl
stdcall StdOut, [sName] ;заголовок
mov ecx, [count] ;число элементов
mov esi, [Array] ;адрес
ArLoop:
lodsd
push ecx
lea ecx,[buf] ;адрес буфера
cinvoke wsprintf, ecx, sFormat, eax
lea eax, [buf]
stdcall StdOut, eax ;выводим
pop ecx
loop ArLoop
stdcall StdOut,lf ;перевод строки
ret
endp

;сортировка пузырьком массива arr с количеством cnt
proc Sort uses esi edi ebx, arr, cnt
mov ebx, [arr] ;адрес массива
xor esi, esi ;первый индекс
mov ecx, [cnt]
dec ecx ;индекс последнего элемента
SortExtLoop: ;первый цикл
lea edi, [esi+1] ;второй индекс
SortIntLoop: ;второй цикл
mov eax, dword[esi*4+ebx] ;первый элемент
cmp eax, dword[edi*4+ebx] ;сравниваем со вторым
jle SortIntNext ;если не больше, то на следующий
xchg eax, dword[edi*4+ebx] ;иначе меняем местами
mov dword[esi*4+ebx], eax
SortIntNext:
inc edi ;на следующий второй
cmp edi, ecx ;циклим до последнего
jbe SortIntLoop
inc esi ;на следующий первый
cmp esi, ecx ;циклим до предпоследнего
jb SortExtLoop
ret
endp

;преобразование строки [string] в знаковое число EAX
proc stoi uses ebx esi edi, string
xor ebx, ebx ;здесь будем стоить число
xor ecx, ecx ;счетчик разрядов
xor edi, edi ;знак числа
mov esi, [string] ;адрес строки
stoi_next:
lodsb ;очередной символ
cmp al, 0dh
je stoi_sign
cmp al, '+'
je stoi_plus
cmp al, '-'
je stoi_menus
cmp al, '0'
jb stoi_error ;любая нецифра,включая 0,- ошибка
cmp al, '9'
ja stoi_error
push eax ;сохраним новый разряд
mov eax, 10
mul ebx ;умножим старшие на 10
test edx, edx
pop edx ;новый
jnz stoi_overflow
test eax, eax
js stoi_overflow
and edx, 0fh ;'0'-'9' -> 0-9
add eax, edx ;добавляем новый разряд
mov ebx, eax
jmp stoi_next ;продолжаем
stoi_plus:
test edi, edi ;уже был знак?
jnz stoi_error
inc edi
jmp stoi_next
stoi_menus:
test edi, edi ;уже был знак?
jnz stoi_error
dec edi
jmp stoi_next
stoi_sign:
mov eax, ebx ;число возвращаем в eax
test edi, edi ;учтем знак (0,1 > 0), (-1 < 0)
jge stoi_ret
neg eax
stoi_ret:
clc
ret
stoi_error:
mov eax, 1 ;ошибка формата числа
stc
ret
stoi_overflow:
mov eax, 2 ;ошибка переполнения
stc
ret
endp

;функция f(x), с проверкой корректности x, должен быть в интервале ]1,10]
proc f, x
cmp [x], 5
jg cmp_return_b
cmp [x], 1
jle f_err
mov eax, [A+4*2] ;третий элемент массива А
mov dl, 'a' ;для вывода сообщения
clc
ret
cmp_return_b:
cmp [x], 10
jg f_err
mov eax, [B+4*2] ;третий элемент массива В
mov dl, 'b' ;для вывода сообщения
clc
ret
f_err:
stc ;x вне интервала
ret
endp

proc Main uses ebx
locals
buf db 16 dup (?) ;буфер для преобразования числа в строку
endl
;выведем массивы до сортировки
mov eax, sA
lea ecx, [A]
stdcall Print, eax, ecx, 10
lea eax, [sB]
lea ecx, [B]
stdcall Print, eax, ecx, 10

;сортируем
stdcall Sort, A, 10
stdcall Sort, B, 10

;сообщение о массивах после сортировки
stdcall StdOut, sAfter

;выведем массивы после сортировки
mov eax, sA
lea ecx, [A]
stdcall Print, eax, ecx, 10
lea eax, [sB]
lea ecx, [B]
stdcall Print, eax, ecx, 10

stdcall StdOut, sEnter
lea ebx, [buf]
stdcall StdIn, ebx, 16 ;вводим строку-число Х

stdcall stoi, ebx ;преобразовываем в число
jc NumError
mov [X], eax

;считаем eax = f(x)
stdcall f, eax
jc PrintError ;ошибка?

;сформируем сообщение f(число) = a|b = число
lea ebx, [buf]
invoke wsprintf, ebx, sF, [X], edx, eax
;выведем
stdcall StdOut, ebx
ret
PrintError:
stdcall StdOut, sOutOfRange
ret
NumError:
dec eax
mov eax, [TableNumErrors+eax*2]
stdcall StdOut, eax
ret
endp

; #########################################################################

section '.idata' import data readable writeable

library kernel32,'KERNEL32.DLL',\
user32,'USER32.DLL'

include 'api\kernel32.inc'
include 'api\user32.inc'
[/code]
5
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Мастер-Эксперт
425
4118
17.01.2012, 20:06
общий
Адресаты:
А как можно сделать, чтобы Х можно было вводить руками?
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
давно
Посетитель
7438
7205
17.01.2012, 21:40
общий
Адресаты:
Сделаем
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
17.01.2012, 23:53
общий
Адресаты:
Сказано-сделано
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Мастер-Эксперт
425
4118
18.01.2012, 12:04
общий
Адресаты:
Спасибо!
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
Форма ответа