Назад На главную Вперед
        Как МЫ помогали Васе учить таблицу умножения.
 

самое начало ...


- Ну что ты друг Васька приуныл, чего ты тут над учебником пыхтишь.
Это я нашего младшего братишку спрашиваю. Он у нас еще в начальной школе учится, а я то уже в институте.
- Да вот, таблицу умножения задали. Хоть бы помог.
- А чего тут помогать, запиши ее на бумажке, посмотрел, бумажку закрыл, а сам в уме повторяешь, так и запомнишь.
- Опять на бумажке, сам то все на компьютере делаешь. Нет бы мне на компьютере таблицу нарисовал.
- Ну рисовать я не буду, а вот программу составить могу. А вот хоть на Basic-е: самый простой вариант. Вы на какую цифру умножение проходите?
- Пока на 3. А завтра уже наверно на 4 зададут.
- Значит программа должна уметь выдавать таблицу на все цифры от 1 до 9. Ну и что? А мы ее заставим спросить, на какую цифру таблицу выдавать. Вот смотри. Это так называемая блок-схема я ее из тетради по информатике за девятый класс перерисовал. Здесь же и программа.

Начало программы

Ввод сомножителя

Присвоить второму 1

Получить произведение

Вывести его на экран

Увеличить второй на 1

Проверить не больше ли он 10

Выход


REM Таблица УМНОЖЕНИЯ

Input "Введи первый сомножитель ";A


B = 1

PR:

C = A * B

Print C      

B = B + 1

 

If  B > 10 THEN GOTO KONEC ELSE GOTO PR
 

KONEC:

 А так она на экране выглядит.


Программа просит ввести цифру, на какую нужно эту таблицу выдать. Вводим 6, нажимаем Enter, все результат готов. А программа то всего ничего, 8 строчек.
- Что то твой столбик чисел совсем на таблицу не похож.
 

- Да вообще то ты прав, сейчас поправим. Вот так уже лучше, правда?
- Да, хороше. Ты мне ее на рабочий стол поставь, чтобы я сам запускал.
-
Э-э-м, да. Тут еще надо заставить ее запуститься. Видишь ли, вообще то программа на Basic-е это не программа, а текстовый файл, который нужно в оболочку среды программирования поместить, а потом и запускать. Но для нашего случая с Qbasic можно запуск программы прямо в командной строке сформировать. Правда после отработки, все равно, придется из этой оболочки выходить. Но это несложно, я тебе покажу.
- Нет уж, ты мне тут всего наговорил, я ничего не понял. Давай делай, чтобы без всяких оболочек.
 

- Тогда нужно чтобы эта программа стала программой, то есть файлом с расширением exe или com . А это мы в усеченной версии Basic-а не сделаем. Ну писать программу так писать, а вот смотри мы ее сейчас в два счета: раз и готово.
    Смотри какая программа получилась и небольшая и программой без оболочки можно сделать.

#include <stdio.h>
main() {
int i, a, pr;
printf("Введи первый сомножитель ");
scanf("%d",&a);
for (i=1; i<=10; i++){
pr = a * i;
printf("%d x %d = %d\n", a, i, pr);
}
getch();
}
 


- Вот так небольшая. На бейсике меньше была, а это, вроде, не Бейсик.
- Нет это не Бейсик, это чистый C (СИ) - Язык крутых программистов. На этом языке даже операционные системы написаны.
- И ты тоже можешь операционную систему написать.
- Нет, ну что ты, мы только его основы изучаем, но, при желании, никто не мешает свой уровень повышать.
- А что эти строчки означают, ты хоть можешь рассказать?

- Ну это то легко.

        Самая первая строчка подключает к программе библиотеку, которая дает возможность использовать в нашей программе стандартные функции ввода- вывода. В нашем случае это printf - вывод: в данной ситуации на экран. scanf - ввод: в нашем случае с клавиатуры целого числа, которое и присваивается переменной а. Вернее эта конструкция - &a, посылает значение в память, на которую эта a указывает. И getch - функция считывания кода нажатой клавиши, у нас просто ожидание для обеспечения возможности просмотра результата работы программы.
      Слово main() указывает на начало главной функции программы (в СИ вообще все построено на функциях), а фактически на начало программы. Пустые скобки () показывают, что никаких параметров для обработки мы этой функции не передаем. А начало и конец самой функции обозначаются Открывающей { и закрывающей } фигурными скобками. В третьей строке программы происходит объявление переменных. В отличие от привычного BASIC и PASCAL, вначале указывается тип объявляемой переменной, а уж потом и их имена через запятую. На окончание вычислительного выражения, команды или другой программной конструкции указывает точка с запятой. Вдруг вам захочется ввести их несколько в одной строчке. Все, что заключено в кавычки должно быть выведено на экран.
    Особенностью СИ является то, что о месте выводимых значений переменных вы должны позаботиться заранее, указав шаблон для отвода места в строке для этой переменной, чтобы программа могла туда ее значение поместить. Например %d - для значения переменной целого типа, %s - для переменной типа String и так далее.
    Организация цикла со счетчиком выполнена в привычном виде: начальное значение счетчика, контроль конечного значения, шаг его изменения. Параметры цикла помещаются в круглые скобки, а само тело цикла (набор его команд) в фигурные {}. Значение произведения выводится на экран в виде строки: printf("%d x %d = %d\n", a, i, pr); - где \n - обозначает перевод курсора на следующую строчку для продолжения вывода.

 

- Я тебя очень внимательно слушал, хорошо рассказал, вот немного подрасту, еще раз расскажешь.
- Да что то я, похоже, перемудрил. Давай ка мы лучше Паскаль загрузим, там практически все то же можно сотворить. Вот смотри, 11 строчек, почти как в Бейсике .

Var
P1,I : Integer;

Begin
Write('Введи первый сомножитель: ');
Readln(P1);
For I:=1 to 10 do
Begin
Writeln(P1,' x ',I, ' = ', P1*I);
end;
Readln;
end.

 

И на экран выдается точно также.
Только теперь мы из этой штуки настоящий экзешник сделаем, и на рабочий стол ярлык этой программы поставим, будешь тренироваться.

- Поставил, давай ко я попробую, так первый сомножитель 3, Enter, ага получилось.
Буду теперь учить. А сколько эта программа на диске места занимает.

- Да совсем немного. Несколько килобайт.
- Сколько, сколько? Килобайты?
- Ну да, 2560 байт.
- Программа то малюсенькая, а тысячи байт и выглядит очень скучно.
- Ну тебе не потрафишь. Это же программы для так называемой DOS-платформы. Их, конечно, можно немного приукрасить, но все равно это вам не WINDOWS.
- А мы в чем же тогда сейчас?
- В WINDOWS, конечно. Только программы эти по большому счету не для этой операционки пишутся.
- А ты что для этой операционки не умеешь программы писать.
- Почему не умею? Эх ты, дитятко неугомонное. Ну давай на VB, то есть на Visual Basic-е напишем.
 Вот самый простой вариант таблицы умножения на VB. Посмотри, программа практически ничем не отличается от своего досовского собрата. Всей то и разницы, что запускается с кнопки на форме. Никакого тебе объявления переменных, никакого тебе преобразования типов. Совершенно свободный стиль программирования.

Private Sub Command1_Click()
P1 = InputBox("Введи первый сомножитель")
For I = 1 To 10
Print P1; " x "; I; " = "; P1 * I
Next
End Sub
 

- Но все таки VB это объектно-ориентированный язык, и написать ту же самую программу на нем можно и подругому. Например так.
 

Dim P1 As Integer
Dim I As Integer

Private Sub Command1_Click()
Text1.Text = ""
P1 = Val(Text2.Text)
For I = 1 To 10
Text1.Text = Text1.Text & _
Str(P1) & " x " & Str(I) & " = " & _
Str(P1 * I) & vbCrLf
Next I
End Sub

Private Sub Command2_Click()
End
End Sub
 


- Объявить, как положено, переменные, ввод и вывод сделать в текстовые поля. Преобразовать переменные в требуемые типы данных. Сделать кнопку выхода из программы. Правда после компиляции обе программы и первая и вторая имеют совершенно одинаковый размер 20480 байт.
- Где же спрятались эти дополнительные поля и кнопки?
- Это ты у меня спрашиваешь...
- Ну вот и здорово. Вторая программа на Visual Basic выглядит уже совсем красиво.
А можно я ее Кольке отнесу, мы вместе умножать потренируемся. Запиши мне ее на дискету.

- Записать то можно, но вот ты случайно не помнишь, какая у твоего Кольки операционная система установлена.
- Нет не помню, но компьютер у него, на самом деле, старенький.
- Значит может быть и Windows 98.
- Ну и что, эта ваша программа в этм виндоусе не заработает.
- Заработать то она заработает, но только если у него на компьюте так называемая run-time библиотека от Visual Basic-а есть. Хоть програма на VB и небольшая по размеру но требует наличия на компьютере этой самой библиотеки.
- Так запиши мне ее на дискету.
- На дискету она не уберется, если только ее не упаковывать. А ты сможешь ее там распаковать.
- Это я не знаю. Ты мне лучше ее на Flash-ку запиши.
- Так ведь Flash-ки на WIN98 не распознаются, если операционка непропатченая.
- Ну все, ты мне опять мозги своими проблемами запудрил, а собирался помочь. Что же совсем никак нельзя простую таблицу умножения сделать, чтобы на любом компьютере работала. Вон в интернете сколько всего и на всех компьютерах смотрят.
- А и то верно, а что если нам WEB-страничку сделать с таблицей умножения, а WEB-браузеры на каждом компьютере есть. Итак начнем.
Раз нам нужно, чтобы произведения с разными цифрами выводились статической страничкой здесь не обойтись.
- Опять ты што-ли на каком то языке программу писать будешь?
- Да прийдется. Только этот язык, который JavaScript называется во всех современных просмотрщиках Web-страниц, как говорят, ВЕБ-браузерах, есть.
Так так, еще немного, ну вот, и готово.
Хочешь ее проверить, тогда сюда.
- Ну ка, чево это ты тут насочинял, хоть бы рассказал немного.
- Ладно, но только кратко.

<html>
<head>

//-- это два тега (метки такие), по ним, то есть по тегам, браузер узнает как на страничке информацию показывать. Эти два начало странички и ее заголовок обозначают.
А дальше описывается функция на языке JavaScript, которая и строит таблицу умножения. У функции, как и положено название есть и в скобках параметр, который ей для обработки передают. Obj - объект какой то, шучу - это то, с чем наша функция будет работать.
    А дальше (в следующей строчке) мы видим, как  в этом объекте чистится  tablum - наша таблица, чтобы всегда с чистого листа ее выводить. А потом функция в цикле 10 раз в таблицу строчку нашего произведения выводит, беря один сомножитель из поля expr, а другой число i, которое с каждым разом больше на единицу становится. Так после 10 шагов наша полная таблица вырисовывается.

<SCRIPT>
function comptab(obj) {
obj.tablum.value=''
for (i=1; i<11; i++) {
obj.tablum.value=obj.tablum.value + eval(obj.expr.value) +
 ' x '+ eval(i) + ' = '+ eval(obj.expr.value) * i + "\r\n"
}
}
</SCRIPT>

</head>
<body>


//-- А это уже body - с английского переводится: тело, только не человеческое, а страничкино, то есть ее главная часть, где все для ее показа записано.
Сначала заголовочек нашей страницы, говорит, что это не таблица розыгрыша лотереи, а какая надо. Потом форма создается.
- А зачем она нужна?
- А зачем все формы нужны? Например в песочнице, чтобы из песка фигурку сформировать, а литейная, чтобы деталь нужную. А наша форма, чтобы на ней сформировать поле для ввода, кнопку для запуска расчета и текстовое пространство для вывода. Вот собственно и все. Загружаем страницу в браузер, вводим значение одного сомножителя и жмем на кнопку расчет.

<h4>Таблица умножения </h4>
<FORM NAME="evalform">
Введи 1-й сомножитель:
<INPUT TYPE=text NAME="expr" SIZE=5>
<br>
<INPUT TYPE=button VALUE="Расчет" onClick="comptab(this.form)">
<TEXTAREA Name="tablum" ROWS=12 COLS=20 WRAP=soft >
</TEXTAREA>

</FORM>
</body>
</html>

 

 

  - Все ты непонятно объяснил, поля да формы, а тут одни иностранные слова написаны.
- Так слова это, как раз и есть те самые метки (теги), которые объясняют программе просмотра страниц, как эта страница должна выглядеть. А, чтобы разобраться, возьми любую книгу по основам языка гипертекстовой разметки HTML и про каждый тег почитай, сразу все ясно станет.
- Ладно потом почитаю. Записывай программу.
-
Это не программа, а WEB-страница, каких в Интернете много.
- Ну ладно, страница так страница. Но неужели приличную простенькую программу нельзя без всяких браузеров использовать.


- Почему нельзя, можно, но, чтобы программа без всяких библиотек работала ее нужно на таком языке писать, чтобы она прямо с операционной системой работала.
 - ... На каком, например?
  - Сейчас мы попробуем очень маленькую программу таблицы умножения сделать. Берем простой текстовый редактор. Для самого маленького размера будем программу типа com делать. Это самый первый тип программ. Сам файл - просто кусочек памяти, он в эту память загружается и с определенного места процессору на съедение, ой прости, на обработку отдается.
- Ты говоришь: файл - кусок памяти, а что программы и другие бывают.
- Бывают. Когда компьютеры все совершенствовались, то приходилось по разному выкручиваться, чтобы программы больших размеров писать. Они по сегментам в памяти располагались, но сейчас опять к плоской структуре перешли: так удобней, адрес памяти любого куска программы простым числом обозначается.
     Что то мы с тобой разболтались, а программа на ассемблере почти готова. Конечно, специалисты в ней кучу недоработок найдут. Скажут у ассемблера еще есть название макроассемблер, а вы тут весь код досовским выводом утыкали. Ну мы ее потом доработаем.
- А папа говорит: потом - это значит никогда.
- Ты уже начинаешь умные мысли выдавать. Посмотри лучше на программу, я тут ее кратенько прокомментировал.

 

.model tiny
.386
.code

org 100h

start:

Vvod:



mov ah,9


mov dx, OFFSET Prigl


int 21h


mov ah,1

int 21h



cmp al,'1'
jl ErrMes

cmp al,'9'
jg ErrMes


mov ah,0

sub al,'0'


mov s1, al

add s1, 30h
push ax
mov ah,1
int 21h
cmp al,0Dh
pop ax
jne Vvod

mov somn1, ax


VivTabl:
mov ah,9
mov dx, OFFSET Return
int 21h
mov bx, somn2


mov s2, bl
cmp bl, 10
jne NotTen

mov d2, '1'

mov s2, '0'
jmp Ten
NotTen: add s2, 30h

Ten: mov ah,9
mov dx, OFFSET s1
int 21h

mov ax,somn1
mul somn2
mov cx,0

NexDiv: mov dx,0
div Des
push dx

inc cx

cmp ax,0

jne NexDiv

mov ax,0200h
PrnSym: pop dx
add dl,30h
int 21h
loop PrnSym


inc somn2
cmp somn2, 11

jl VivTabl
jmp Konec


ErrMes: mov ah,9
mov dx,OFFSET ErrorMes
int 21h

Konec: mov ah, 0



int 16h
mov ax,4C00h


int 21h

Des dw 10

somn1 dw 0
somn2 dw 1
s1 db 0

Znak db ' x '
d2 db ' '
s2 db 1
EndString db ' = $'
Prigl db 'Введите первый сомножитель от 1 до 9. $'
ErrorMes db 'Вы ошиблись при вводе цифры.',0Dh,0Ah,'$'
Return db 0Dh,0Ah,'$'

end start
  ; Объявление модели памяти программы
; Инструкции какого процессора нужно использовать
; Говорит что сегмент кода, а не другой, начинается,
; хотя для COM он всегда один
; Указывает, что программа начинается на расстоянии 256
; байт от начала выделенного ей блока памяти.
; А вот именно здесь она и начинается.

; Это метка. На нее переход можно делать, условный или
; безусловный.
; Ассемблерщиков никто не ругает за команду GOTO, простите JMP
; Этот параметр указывает, какая функция DOS
; будет вызываться. 9 в регистр ah это для
; вывода на экран.
; Здесь мы задаем адрес начала нашего текста,
; который надо будет выводить. Это приглашение
; ввести сомножитель.
; Это номер прерывания DOS, которое разную
; работу в операционке выполняет

; А это функция отлавливает символ, с
; клавиатуры введенный
; И на экране его копию (эхо) показывает.
; Теперь нам нужно проверить, не введет ли кто
; символ вместо цифры.

; Сравним не меньше ли он единицы
; Если меньше то прыгнем на метку где
; программа ошибки обрабатывает
; И не больше ли чем 9
; Прыгнем туда же, где вас программа отругает
; за вашу невнимательность

; Почистим, на всякий случай, половинку
; регистра AX
; Вычтем 0 из символа числа которое мы ввели,
; и вот мы уже имеем не символ обозначающий
; цифру а число.
; Поместим его в переменную s1, это первый
; сомножитель
; А теперь сделаем из числа символ
; спрячем значение AX в стеке
; Опять ожидание ввода символа
; Получаем его
; Проверяем а не Enter ли это.
; Вытащим из стека AX
; А вот если не Enter, то опять будем
; ждать ввода символа
; Ага Enter нажали, значит сомножитель введен.
; Поместим его в нужное место

; Начинаем таблицу выводить
; Вывод на экран
; Для начала перескочим на следующую строчку
; Чтобы таблица выглядела таблицей.
; Несколько последующих манипуляций для вывода
; числа 10 при умножении в последней строчке
; таблицы.
; Это второй сомножитель для вывода
; Сравним его с 10
; Нет не АЙС, тьфу не 10, прыгаем на получение
; и вывод этого односимвольного числа.
; А вот если 10, то в разряд десятков поместим
; единицу.
; А в разряд единиц 0.
; Перепрыгнем вывод обычной цифры.
; Для не десяти получаем из цифры символ
; добавив к ней значение символа нуль.
; Вывод на экран
; Выводим строку перемножения чисел.


; Помещаем в AX первый сомножитель
; Умножаем его на второй
; Чистим регистр CX, чтобы начать считать
; количество цифр в числе.
; Подготовим DX, очистив его
; Разделим AX на 10
; Спрячем количество полных десятков или
; единиц в стек
; Увеличив CX запомним, что произведение, как
; минимум уже одна цифра.
; Проверим, а не меньше ли количество десятков
; произведения, чем 0.
; Если больше, делим число еще раз на 10,
; прыгнув на метку NexDiv
; А этот параметр для вывода символа на экран.
; Вытащим десятки, или что то другое из стека
; Конвертируем цифру в символ
; Вызовем команду вывода.
; Если CX был не единица, то будем крутиться
; в цикле пока не выведем все символы.

; Увеличим второй сомножитель на единицу
; Проверим не превысило ли его значение
; число 10.
; Если меньше продолжаем формировать таблицу.
; Иначе прыгеаем на конец программы, пропуская
; вывод сообщения об ошибке.

; Это вывод сообщения об ошибке.
; Если вместо цифры ввели другой символ.


; Эта функция просто ждет нажатия клавиши,
; чтобы узнать что это за клавиша. Но нам она
; не нужна. Мы просто любуемся
; выведенной таблицей

; Это все та же функция (подпрограммка) DOS.
; Она заканчивает работу программы и освобождает
; память.
; Так называемый сервис DOS

; Это число 10, на которое мы делим двузначное,
; чтобы отделить десятки от единиц.
; Здесь хранится значение первого сомножителя
; А здесь второго.
; А это хитрая конструкция для вывода строки
; из
; двух сомножителей и знака равно.


; Вывод заканчивается на этом знаке.





; Это просто конструкция для перевода вывода
; на следующую строку
; Конец того самого старта вначале, а
; значит конец программе.

 

- Ну что все понятно?
- Ага! Все, все понял и даже больше.
- Что то ты слишком грустно реагируешь. Что просил то и получил. И маленькая, всего 287 байт, и без всяких оболочек запускается.
- Опять черный экран - белые цифры, а, что, покрасивее нельзя?
- Почему нельзя, все можно, если очень захотеть, можно в космос полететь. Но писать программы на ассемблере для WINDOWS, это отдельная история.
Если ты подождешь некоторое время, то можно будет тебе ее продемонстрировать.
- Я подожду. А как эта программа получается? Для нее тоже оболочка программирования есть?
- Нет, изначально никакой оболочки не было. Все существующие это просто специализированные текстовые редакторы. Программа может быть написана, как и все остальные (кроме VB), в обычном текстовом редакторе. Пакет для создания программ на ассемблере для WINDOWS можно в Internet найти. Там он называетсяMASM32. Примеров в этом пакете, наверное, на все случаи жизни. Кто захочет размять свои мозги, была бы только охота.
    Так как программирование на ассемблере для WINDOWS имеет свою специфику, объяснять буду только самую суть программы, если кому захочется в это погрузиться то вперед, преград никаких нет. Итак приступим.

    .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
    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib

; В заголовке назначается модель памяти, обрати внимание: FLAT - плоская, как в
;старом досовском COM-файле, прототип главной функции и список подключаемых
; файлов библиотек и описаний

   
.data
    ClassName db "SimpleWinClass",0
    AppName db "Таблица умножения",0
    ButtonClassName db "button",0
    ButtonText db "^ Введи сомножитель и нажми кнопку ",0
    EditClassName db "edit",0

; Так как мы делаем таблицу умножения то зададим ее в виде блока данных, которые будем заполнять
   
blok1 db " x 1 = ",0Dh,0Ah
    db " x 2 = ",0Dh,0Ah
    db " x 3 = ",0Dh,0Ah
    db " x 4 = ",0Dh,0Ah
    db " x 5 = ",0Dh,0Ah
    db " x 6 = ",0Dh,0Ah
    db " x 7 = ",0Dh,0Ah
    db " x 8 = ",0Dh,0Ah
    db " x 9 = ",0Dh,0Ah
    db" x 10 = ",0Dh,0Ah,0
    smn2 db 1
    Des dw 10
    mnn dw 0
; Количество цифр в произведении

; Список неопределенных данных переменных
    .data?
    smn1 db 1 dup(?)
    buffer db 512 dup(?)
    hInstance HINSTANCE ?
    CommandLine LPSTR ?
    hwndButton HWND ?
    hwndEdit HWND ?
    hwndVivod HWND ?


;Список определяемых констант
    .const
    ButtonID equ 1
    EditID equ 2
    VivodID equ 2
    IDM_GETTEXT equ 3

    .code

;А вот и кодовый сегмент и начало программы
    start:
    invoke GetModuleHandle, NULL
    mov hInstance,eax
    invoke GetCommandLine
    invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
    invoke ExitProcess,eax

; Дальше идет главная процедура программы, которая создает главное окно и
; заставляет крутиться цикл получения и обработки сообщений
; В Windows почти вся работа на приеме и отправке сообщений построена

    WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
    LOCAL wc:WNDCLASSEX
    LOCAL msg:MSG
    LOCAL hwnd:HWND
    mov wc.cbSize,SIZEOF WNDCLASSEX
    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_BTNFACE+1
    mov wc.lpszClassName,OFFSET ClassName

; Загрузим иконку для показа в программе, чтобы по нашей иконке нашу программу от других отличать.
    invoke LoadIcon,hInst,500 ; ID - Иконки
   mov wc.hIcon, eax
   mov wc.hIconSm, eax

; Курсор, если хотим особенный иметь
    invoke LoadCursor,NULL,IDC_ARROW
    mov wc.hCursor,eax

; Класс окна мы уже описали выше, теперь его нужно зарегистрировать, чтобы ОС
; и другие программы знали о существовании экземпляра объекта этого самого класса.

    invoke RegisterClassEx, addr wc
    INVOKE CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR AppName,\
    WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
    CW_USEDEFAULT,320,400,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 endp

; Раз у нас есть окно то должна быть процедура, которая им управляет
; На себя берем только создание, удаление окна и вывод нашей таблицы

    WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
    .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 ES_AUTOHSCROLL or ES_MULTILINE ,\
    10,100,280,250,hWnd,VivodID,\
    hInstance,NULL
    mov hwndVivod,eax

; Создадим дочернее окошко для ввода значения первого сомножителя
    invoke CreateWindowEx,WS_EX_CLIENTEDGE, ADDR EditClassName,NULL,\
    WS_CHILD or WS_VISIBLE or WS_BORDER or ES_LEFT or\
    ES_AUTOHSCROLL,\
    10,10,50,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,\
    10,55,280,25,hWnd,ButtonID,hInstance,NULL
    mov hwndButton,eax
; Начинается обработка команд
   
.ELSEIF uMsg==WM_COMMAND
    mov eax,wParam
    .IF lParam==0

; Вывод таблицы уножения
   
.IF ax==IDM_GETTEXT
    invoke GetWindowText,hwndEdit,ADDR smn1,2
    push edi
;Перед выводом формируем блок с данными: фактически саму таблицу
   
mov edi,offset blok1 + 1
    mov al, smn1
    mov byte ptr [edi], al
    mov ecx, 9
    addsmn: add edi,15
    mov byte ptr [edi], al
    loop addsmn

    mov al,smn1
    sub al, '0'
    mov smn1, al
    mov edi,offset blok1+11
    nexchf:
    mov al,smn1
    mul smn2
    mov cx,0
    NexDiv: mov dx,0
    div Des
    push dx
    inc cx
    cmp ax,0
    jne NexDiv
    mov mnn, cx
    NexSym: pop dx
    add dl,30h
    mov byte ptr [edi], dl
    inc edi
    loop NexSym
    cmp mnn, 1
    je onchar
    dec edi
    onchar:add edi,14
    inc smn2
    cmp smn2,10
    jna nexchf
    pop edi

    mov smn2,1
; А теперь просто выведем этот блок в нужное окошко
   
invoke SetWindowText,hwndVivod,ADDR blok1
;А еще для верности в окошко с ообщением
   
invoke MessageBox,NULL,ADDR blok1,ADDR AppName,MB_OK
; Почистим блок данных, вдруг потребуется таблица на другую цифру
   
push edi
    mov ecx,9
    mov edi,offset blok1+11
    chist: mov byte ptr [edi], ' '
    inc edi
    mov byte ptr [edi], ' '
    dec edi
    add edi,15
    loop chist
    pop edi


    .ELSE
    invoke DestroyWindow,hWnd
    .ENDIF
    .ELSE
    .IF ax==ButtonID
    shr eax,16

;Если была нажата кнопка то послать сообщение нашему окну, чтобы оно выводило таблицу
   
.IF ax==BN_CLICKED
    invoke SendMessage,hWnd,WM_COMMAND,IDM_GETTEXT,0

    .ENDIF
    .ENDIF
    .ENDIF
    .ELSE
    invoke DefWindowProc,hWnd,uMsg,wParam,lParam
    ret
    .ENDIF
    xor eax,eax
    ret
    WndProc endp
    end start
 


 
- Ну вот посмотри что получилось. 

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


- Да, вижу, а то, подозрительно получается, для чего размер программы десяток килобайт, если все тоже самое сотня байт может сделать.
- Хотя, если посмотреть, в ассемблере для WINDOWS очень часто не напрямую процессором командуют, а API функции используют, но это в том случае, когда операционная система уже позаботилась о том, что ты хочешь сделать. Как итог: да можно было только блок, который саму таблицу создает показать, но, по себе знаю, не все начинающие, имея такой блок, превратят его в работающую программу, а здесь все от начала до конца. Хотя, как ты можешь видеть, комментарии здесь довольно скудные. Это потому, что прямо в программе очень сложно все объяснить, И на одной программе все равно ассемблер для WINDOWS не выучишь. 
      

- А на каком языке ты мне таблицу еще не запрограммировал.
- На многих, на
Delphy, на C++, ну, Java еще осталась. А что, давай мы тебе программу сделаем и на телефон закачаем, будешь на уроках таблицу по телефону подглядывать.
 - В телефоне и так калькулятор есть без всякой программы.
- Калькулятор это неинтересно, ну как хочешь, а я все равно ее напишу...
 

Смотри: пока мы тут экспериментировали, папа с работы пришел....

  Назад На главную Вперед  

Другая информатика. (C) Публикация на draginf.ru. При использовании материалов ссылка на сайт обязательна.