Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Ассемблер? Это просто! Учимся программировать


Хостинг портала RFpro.ru:
Московский хостер
Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Лучшие эксперты данной рассылки

Boriss
Статус: Академик
Рейтинг: 2522
∙ повысить рейтинг »
Абаянцев Юрий Леонидович aka Ayl
Статус: Профессионал
Рейтинг: 2007
∙ повысить рейтинг »
vladisslav
Статус: 6-й класс
Рейтинг: 1254
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И СОФТ / Программирование / Assembler (Ассемблер)

Номер выпуска:1382
Дата выхода:13.11.2010, 14:00
Администратор рассылки:Лысков Игорь Витальевич (Старший модератор)
Подписчиков / экспертов:224 / 66
Вопросов / ответов:2 / 2

Вопрос № 180574: Помогите. В матрице C[1..N,1..M] целых чисел определить, есть ли “седловая” точка (“седлом” называется элемент матрицы, минимальный в строке, и, одновременно, максимальный в столбце). Если такой элемент есть, вывести значение и его индексы. Вопрос № 180612: Добрый день! Подскажите, как можно обработать нажатие кнопки «Далее >», чтобы появлялось не MessageBox, как у меня сейчас в программе, а такое же зарегистрированное в WinMain proc окно, но с другим заголовком окна и другим текстом вопроса? Кнопка ...



Вопрос № 180574:

Помогите.
В матрице C[1..N,1..M] целых чисел определить, есть ли “седловая” точка (“седлом” называется элемент матрицы, минимальный в строке, и, одновременно, максимальный в столбце). Если такой элемент есть, вывести значение и его индексы.

исходные данные в файлике pas, сортировка в файлике obj

Отправлен: 05.11.2010, 05:16
Вопрос задал: Посетитель - 342589 (Посетитель)
Всего ответов: 1
Страница вопроса »


Отвечает Зенченко Константин Николаевич (Модератор) :
Здравствуйте, Посетитель - 342589!

Код программы на Pascal:
Код:
const
n=5;
m=6;
type
tMass=array[1..n,1..m]of integer;
var
c:tMass;
i,j:integer;
{подгружаем модуль}
{$L d:\_cat_xp3\asm_lib\q180574.obj}
function sedlo(var a:tMass;var b,c:integer):boolean;external;
{контрольная подпрограмма}
function Z(var a:tMass;var b,c:integer):boolean;
var
d,e,f,g:integer;
begin
for d:=1 to b do
begin
f:=1;
{ищем минимум}
for e:=f+1 to c do
if a[d,e]<a[d,f] then f:=e;
g:=1;
for e:=g+1 to b do{проверяем условие}
i f a[e,f]>a[g,f] then g:=e;
if a[d,f]=a[g,f] then break;
end;
Z:=a[d,f]=a[g,f];
b:=d;
c:=f;
end;
begin
{сбросим генератор случайных чисел и создадим массив}
randomize;
for i:=1 to n do
begin
for j:=1 to m do
begin
c[i,j]:=random(50);
write(c[i,j]:3);
end;
writeln;
end;
{запускаем проверку массива двумя функциями}
i:=n;
j:=m;
if Z(c,i,j) then writeln('C[',i,',',j,']:=',c[i,j])
else writeln('No');
i:=n;
j:=m;
if sedlo(c,i,j) then writeln('asm-C[',i,',',j,']:=',c[i,j])
else writeln('asm-No');
{принудительно создаем "седло"}
for i:=1 to m do C[4,i]:=10;
for i:=1 to n do C[i,3]:=8;
C[4,3]:=9;
for i:=1 to n do
begin
for j:=1 to m do
write(c[i ,j]:3);
writeln;
end;
{проверка созданой точки}
i:=n;
j:=m;
if Z(c,i,j) then writeln('C[',i,',',j,']:=',c[i,j])
else writeln('No');
i:=n;
j:=m;
if sedlo(c,i,j) then writeln('asm-C[',i,',',j,']:=',c[i,j])
else writeln('asm-No');
readln;
end.


Код программы на ассемблере:
Код:
model medium
public sedlo
.code
.186
;
;function sedlo(var a:tMass;var b,c:integer):boolean;
sedlo proc near
arg_3 = dword ptr 4 ; j:integer
arg_2 = dword ptr 8 ; i:integer
arg_1 = dwor d ptr 0Ch ; c:tMass
;создаем стековый кадр
push bp
mov bp, sp
;загружаем количество строк в массиве
les di,[ bp + arg_2 ]
mov cx,es:[ di ];
;загружаем указатель на массив
les di,[ bp + arg_1 ]
mov si,di
mov bx,di
;начинаем цикл поиска
isBigLoop: push cx
;загружаем количество элементов в строке
les di,[ bp + arg_3 ]
mov cx,es:[ di ]
;сбросим указатель и входим в цикл
xor di,di
jmp isMinBegin
;переходим к следующему проверяемую элементу
isMinLoop: add di,2
;сравниваем элементы
cmp ax,es:[ bx + di ]
jle isBig;
;запоминаем очередной минимальный элемент
isMinBegin: mov ax,es:[ bx + di ]
mov dx,di
isBig: loop isMinLoop
;запоминаем указатель на столбец и начало строки
push dx
push bx
push es
;устанавливаем указатель на на столбец
mov bx,si
add bx,dx
;загружаем счетчим цикла
les di,[ bp + arg_2 ]
mov cx,es:[ di ]
;загружаем и считаем длину строки
les di,[ bp + arg_3 ]
mov dx,es:[ di ]
shl dx,1
;востанавливаем сегмент массива
pop es
xor di,di
;цикл проверки "седла"
isMaxLoop: cmp ax,es:[ bx + di ]
jl isSmall;
add di,dx
loop isMaxLoop
;нашли "седло" считаем индекс строки
pop ax
sub ax,si
mov cx,dx
xor dx,dx
div cx
;возвращаем значение
inc ax
les di,[ bp + arg_2 ]
stosw
;считаем столбец и возвращаем значение
pop ax
shr ax,1
inc ax
les di,[ bp + arg_3 ]
stosw
;удаляем счетчик основного цикла и возвращаем "ИСТИНУ"
pop cx
mov ax,1
jmp isExit
;востанавливаем начало строки и переходим к следующей
isSmall: pop bx
add bx,dx
pop dx
pop cx
loop isBigLoop
;не нашли возвращаем "ЛОЖЬ"
xor ax,ax
isExit: mov sp,bp
pop bp
retn 0Ch
sedlo endp
end

Проверялось с помощью ТР7.0 и TASM 2.0.
Программа создает массив с помощью генератора случайных чисел. Проверяется этот массив с помощью контрольной функции написанной на паскале и функции написаной на ассемблере. Т.к. вероятность создания нужного массива очень мала, то "седло" создается принудительно с элементами в строке/столбце равными: 10,9,8. После этого производится аналогичная проверка двумя функциями.
Функции производят поиск первой седловой точки в массиве и выводят об этом сообщение. Остальные точки игнорируются.
вопросы по коду задавайте в мини-форуме.
Удачи!
-----
Итерация от человека. Рекурсия — от Бога. — Л. Питер Дойч

Ответ отправил: Зенченко Константин Николаевич (Модератор)
Ответ отправлен: 10.11.2010, 14:58
Номер ответа: 263944
Украина, Киев
Тел.: +38-097-238-60-03
Адрес: Украина, Киев

Оценка ответа: 5
Комментарий к оценке:
спасибо.

Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 263944 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:


  • Вопрос № 180612:

    Добрый день! Подскажите, как можно обработать нажатие кнопки «Далее >», чтобы появлялось не MessageBox, как у меня сейчас в программе, а такое же зарегистрированное в WinMain proc окно, но с другим заголовком окна и другим текстом вопроса? Кнопка и поле ввода в новом окне остаются прежними. Не знаю, насколько это правильно, но пытался после нажатия кнопки:
    .IF ax==ButtonID
    shr eax,16
    .IF ax==BN_CLICKED
    вызвать второе окно с помощью
    INVOKE CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR AppName2,\
    WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,\
    540,480,NULL,NULL,hInst,NULL
    но компилятору чем-то не понравился хендл программного модуля hInst, мне пришлось ввести переменную MYhInst dd ? и заменить hInst на MYhInst. Потом создавал на новом окне новую кнопку, текст, поле ввода, заголовок. При работе программы получалось почти всё, кроме текста: во втором окне он был таким же, как и в первом. Вдобавок второе окно перекрывало первое, а мне нужно, чтобы было всегда только одно окно: или первое, или второе, но не оба вместе. Вот как переделать эту нижеприведённую программу?

    Отправлен: 08.11.2010, 02:43
    Вопрос задал: Adsorores (Посетитель)
    Всего ответов: 1
    Страница вопроса »


    Отвечает Лысков Игорь Витальевич (Старший модератор) :
    Здравствуйте, Adsorores!
    Вы избрали порочный путь...
    1) У Вас текст вопроса рисуется в общей отработке WM_PAINT, поэтому он будет одинаков во всех окнах
    2) Если создаете новое окно, то для него надо создавать свою отработку очереди сообщений.
    Придется также разграничивать функцию окна...
    Это все можно сделать, но зачем идти этим путем, зачем усложнять себе жизнь?!
    Гораздо проще работать в одном окне. Просто рисуем новый вопрос и все! В Вашем случае это можно
    сделать, например, введя переменную с адресом строки вопроса. И следим, с каким вопросом работаем...

    Кстати, переменная hInst действительна только внутри подпрограммы WinMain, Вы же хотели ее использовать внутри WndProc,
    что, естественно, является ошибкой. Надо было использовать глобальную переменную hInstance

    Код:
    .386
    .model flat,stdcall
    option casemap:none
    WinMain proto :DWORD,:DWORD,:DWORD,:DWORD
    include \masm32\include\windows.inc
    include \masm32\include\user32.inc
    include \masm32\include\kernel32.inc
    include \masm32\include\gdi32.inc
    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib
    includelib \masm32\lib\gdi32.lib

    .data
    ClassName db "SimpleWinClass",0
    AppName1 db "Окно № 1",0
    AppName2 db "Окно № 2",0 ; заголовок для второго окна
    ButtonClassName db "button",0
    ButtonText db "Далее >",0
    EditClassName db "edit",0

    OurText dd OurText1, OurTex t2, OurText3
    MAX_IDX equ ($-OurText)/4 - 1

    OurText1 db 10,13," Вопрос №1:",0
    OurText2 db 10,13," Вопрос №2: ",0 ; текст для второго окна
    OurText3 db 10,13," Вопрос №3: ",0 ; текст для третьего окна

    TestString db " Программа успешно завершена!",0
    String db "End",0

    .data?
    hInstance HINSTANCE ?
    CommandLine LPSTR ?
    hwndButton HWND ?
    hwndEdit HWND ?

    idxAsk dd ?

    buffer db 512 dup(?)

    .const
    COLOR equ COLOR_BTNSHADOW
    ButtonID equ 1
    EditID equ 2

    .code
    start:
    invoke GetModuleHandle, NULL
    mov hInstance,eax
    invoke GetCommandLine
    mov CommandLine,eax
    invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
    invoke ExitProcess,eax

    WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
    LOCAL wc:WNDCLASSEX
    LOCAL msg:MSG
    LOCAL hwnd:HWND
    mov wc.cbSize,SIZEOF WNDC LASSEX
    mov wc.style,CS_HREDRAW or CS_VREDRAW
    mov wc.lpfnWndProc, OFFSET WndProc
    mov wc.cbClsExtra,NULL
    mov wc.cbWndExtra,NULL
    push hInst
    pop wc.hInstance
    mov wc.hbrBackground, COLOR+1
    mov wc.lpszMenuName,NULL
    mov wc.lpszClassName,OFFSET ClassName
    invoke LoadIcon,NULL,IDI_APPLICATION
    mov wc.hIcon,eax
    mov wc.hIconSm,eax
    invoke LoadCursor,NULL,IDC_ARROW
    mov wc.hCursor,eax
    invoke RegisterClassEx, addr wc

    mov idxAsk, 0

    INVOKE CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR AppName1,\
    WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
    CW_USEDEFAULT,540,480,NULL,NULL,\
    hInst,NULL
    mov hwnd,eax
    INVOKE ShowWindow, hwnd,SW_SHOWNORMAL
    INVOKE UpdateWindow, hwnd
    .WHILE TRUE
    INVOKE GetMessage, ADDR msg,NULL,0,0
    .BREAK .IF (!eax)
    INVOKE TranslateMessage, ADDR msg
    INVOKE DispatchMessage, ADDR msg
    .ENDW
    mov eax,msg.wParam
    ret
    WinMain end p

    WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
    LOCAL hdc:HDC
    LOCAL ps:PAINTSTRUCT
    LOCAL rect:RECT

    .IF uMsg==WM_DESTROY
    invoke PostQuitMessage,NULL
    .ELSEIF uMsg==WM_CREATE
    invoke CreateWindowEx,WS_EX_CLIENTEDGE, ADDR EditClassName,NULL,\
    WS_CHILD or WS_VISIBLE or WS_BORDER or ES_LEFT or\
    ES_AUTOHSCROLL,50,50,160,25,\
    hWnd,EditID,hInstance,NULL
    mov hwndEdit,eax
    invoke SetFocus, hwndEdit
    invoke CreateWindowEx,NULL, ADDR ButtonClassName,ADDR ButtonText,\
    WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON,\
    95,95,80,25,hWnd,ButtonID,hInstance,NULL
    mov hwndButton,eax
    .ELSEIF uMsg==WM_PAINT
    invoke BeginPaint,hWnd, ADDR ps
    mov hdc,eax

    invoke SetBkMode, hdc, OPAQUE ;зададим тип замещен ия старого содержимого :)

    invoke GetSysColor, COLOR
    invoke SetBkColor, hdc, eax

    invoke GetClientRect,hWnd, ADDR rect
    mov ecx, idxAsk
    invoke DrawText, hdc, OurText[ecx*4], -1, ADDR rect, NULL
    invoke EndPaint,hWnd, ADDR ps
    .ELSEIF uMsg==WM_COMMAND
    mov eax,wParam
    .IF ax==ButtonID
    shr eax,16
    .IF ax==BN_CLICKED
    .IF idxAsk < MAX_IDX
    inc idxAsk
    invoke InvalidateRect, hWnd, NULL, 0
    invoke SetFocus, hwndEdit
    .ELSE
    invoke MessageBox,NULL,ADDR TestString,ADDR String,MB_OK
    invoke SendMessage,hWnd,WM_DESTROY,0,0
    .ENDIF
    .ENDIF
    .ENDIF
    .ELSE
    invoke DefWindowProc,hWnd,uMsg,wParam,lParam
    ret
    .ENDIF
    xor eax,eax
    ret
    WndProc endp
    end start

    -----
    Люби своего ближнего, как самого себя

    Ответ отправил: Лысков Игорь Витальевич (Старший модератор)
    Ответ отправлен: 08.11.2010, 05:13
    Номер ответа: 263870
    Украина, Кировоград
    Тел.: +380957525051
    ICQ # 234137952
    Mail.ru-агент: igorlyskov@mail.ru

    Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
    Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 263870 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:


  • Оценить выпуск »
    Нам очень важно Ваше мнение об этом выпуске рассылки!

    Задать вопрос экспертам этой рассылки »

    Скажите "спасибо" эксперту, который помог Вам!

    Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА
    на короткий номер 1151 (Россия)

    Номер ответа и конкретный текст СМС указан внизу каждого ответа.

    Полный список номеров »

    * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов)
    ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
    *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.


    © 2001-2010, Портал RFPRO.RU, Россия
    Авторское право: ООО "Мастер-Эксперт Про"
    Автор: Калашников О.А. | Программирование: Гладенюк А.Г.
    Хостинг: Компания "Московский хостер"
    Версия системы: 2010.6.23 от 10.11.2010

    В избранное