Форум программистов, компьютерный форум, киберфорум
Assembler: Windows/protected mode
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.63/8: Рейтинг темы: голосов - 8, средняя оценка - 4.63
21 / 21 / 20
Регистрация: 05.12.2017
Сообщений: 124

Прекращение работы после закрытия окна с результатами (уравнение)

13.05.2018, 17:36. Показов 1576. Ответов 3
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Дали задание: решить уравнение разными 4-мя способами. Этот способ самый трудный - использование стека + взятие его значений с помощью EBP + обращение к переменным по адресам.
Проблема в том, что после закрытия окна с результатами появляется системная ошибка "Прекращение работы программы".
Как ее исправить? Использую MASM.
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
.486                    
.model flat, STDCALL    
option casemap:none 
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 
.data   
MsgBoxTitle db "Результаты", 0
MsgBoxText db 128 dup(?),0  
format1 db "X*X = ", "%d ",0dh,0ah,             ; формат для вывода результатов в окно
"A*X*X = ", "%d ",0dh,0ah,0dh,
"A*B = ", "%d ",0dh,0ah,
"A*B*D = ", "%d ",0dh,0ah,
"A*B*D/Y = ", "%d ",0dh,0ah,
"A*X*X - A*B*D/Y = ", "%d ",0dh,0ah,0dh,
"f(x) = A*X*X - A*B*D/Y + D = ", "%d ",0    
 
A SWORD     -8d    ; F8h        
B SWORD     6d       ; 6h       
D SWORD     8d     ; 8h
X SWORD     4d     ; 4h
Y SWORD     12d    ; 0Ch    
 
X2    SWORD  ?                   ; x*x = x^2       16d = 10h
Rez1   SWORD  ?                  ; a*x^2              -128d = FF80h
 
AmB   SWORD   ?                     ; a*b             -48d = FFD0h
AmBmD   SWORD   ?                     ; a*b*d         -384d = FE80h
Rez2   SWORD   ?                     ; a*b*d/y        -32d = E0h
 
Rez1sRez2   SWORD   ?                     ; a*x^2 - a*b*d/y       -96d = FFA0h
fx   SWORD   ?                     ; a*x^2 - a*b*d/y + d          -88d = FFA8h    
;=======Addresses==================
addrA DWORD     ?                      
addrB DWORD     ?                  
addrD DWORD     ?                      
addrX DWORD     ?                        
addrY DWORD     ?                        
 
addrX2    DWORD  ?                   ; x*x = x^2       16d = 10h
addrRez1   DWORD  ?                  ; a*x^2              -128d = FF80h
 
addrAmB   DWORD   ?                     ; a*b             -48d = FFD0h
addrAmBmD   DWORD   ?                     ; a*b*d         -384d = FE80h
addrRez2   DWORD   ?                     ; a*b*d/y        -32d = E0h
 
addrRez1sRez2   DWORD   ?                     ; a*x^2 - a*b*d/y       -96d = FFA0h
addrfx   DWORD   ?                     ; a*x^2 - a*b*d/y + d          -88d = FFA8h    
 
.code                   
start: 
MOV addrA, OFFSET A                     ; заносим адресы переменных в переменные, хранящие значения адресов
MOV addrB, OFFSET B
MOV addrD,OFFSET D
MOV addrX,OFFSET X
MOV addrY,OFFSET Y
MOV addrX2,OFFSET X2
MOV addrRez1,OFFSET Rez1
MOV addrAmB,OFFSET AmB
MOV addrAmBmD,OFFSET AmBmD
MOV addrRez2,OFFSET Rez2
MOV addrRez1sRez2,OFFSET Rez1sRez2
MOV addrfx,OFFSET fx
    
PUSH A          ; [EBP+8]
PUSH B                  ; [EBP+6]
PUSH D              ; [EBP+4]
PUSH X                  ; [EBP+2]            ; ESP= FF88 (+2)
PUSH Y                  ; [EBP]
MOV EBP,ESP             ; EBP=ESP для доступа к стеку по EBP
 
MOV AX,[EBP+2]          ; AX = X    ;заносим в АХ значение по адресу ЕВР+6
MUL AX                  ; EAX = AX*AX = X*X
MOV ECX, addrX2         ; ECX = addrX2 , заносим в ЕСХ адрес Х2
MOV [ECX], AX           ; X2 = AX , заносим значение регистра АХ в переменную по адресу в ЕСХ
 
MOV BX,[EBP+8]          ; BX = A
IMUL BX                 ; EAX = AX*BX = X*X*A
MOV ECX, addrRez1         ; ECX = addrRez1 , заносим в ЕСХ адрес Rez1
MOV [ECX], AX           ; Rez1 = AX , заносим значение регистра АХ в переменную по адресу в ЕСХ
 
MOV AX, [EBP+6]         ; AX = B
IMUL BX                 ; EAX = BX*AX = B*A
MOV ECX, addrAmB         ; ECX = addrAmB , заносим в ЕСХ адрес AmB
MOV [ECX], AX           ; AmB = AX , заносим значение регистра АХ в переменную по адресу в ЕСХ
 
MOV BX, [EBP+4]
IMUL BX
MOV ECX, addrAmBmD         ; ECX = addrAmBmD , заносим в ЕСХ адрес AmBmD
MOV [ECX], AX           ; AmBmD = AX , заносим значение регистра АХ в переменную по адресу в ЕСХ
 
MOV BX, [EBP]
IDIV BL                    ; AX/BL = AL
CBW                     ; AL -> AX ; E0 -> FFE0
MOV ECX, addrRez2         ; ECX = addrRez2 , заносим в ЕСХ адрес Rez2
MOV [ECX], AX           ; Rez2 = AX , заносим значение регистра АХ в переменную по адресу в ЕСХ
 
MOV BX, Rez1
SUB BX, AX                 ; BX = BX-AX     ; FFA0
MOV ECX, addrRez1sRez2         ; ECX = addrRez1sRez2 , заносим в ЕСХ адрес Rez1sRez2
MOV [ECX], BX           ; Rez1sRez2 = BX , заносим значение регистра АХ в переменную по адресу в ЕСХ
 
MOV AX,[EBP+4]
ADD BX, AX              ; BX = BX+AX    ;FFA8
MOV ECX, addrfx         ; ECX = addrfx , заносим в ЕСХ адрес fx
MOV [ECX], BX           ; fx = BX , заносим значение регистра АХ в переменную по адресу в ЕСХ
 
invoke wsprintf,                            ;invoke – вызов - wsprintf 
ADDR MsgBoxText,                            ;ADDR - определение адреса MsgBoxText
ADDR format1,                               ;ADDR - определение адреса format1
X2, Rez1, AmB, AmBmD, Rez2, Rez1sRez2, fx               ;данные берутся из переменных
invoke MessageBox, 0,                       ;invoke – вызов функции API MessageBox
ADDR MsgBoxText,                            ;ADDR- определение адреса MsgBoxText
ADDR MsgBoxTitle,                           ;ADDR- определение адреса MsgBoxTitle
MB_OK                
ret     
end start
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
13.05.2018, 17:36
Ответы с готовыми решениями:

Прекращение работы Проводника после обновления ОС
Добрый день! Проблема такая: вчера обновилась винда установка прошла комп выключился сам сегодня включаю идет настройка обновления...

Timer и прекращение его работы после первого тика
Здравствуйте! Недавно на форуме нашёл тему похожую... Там рассказывали, как выполняются периодически действия по таймеру, через...

Уничтожение окна после закрытия
Form1 и Form2 наследники QDialog int openForm(const QString &name) { void *form; if(name == "Форма1") form =...

3
Модератор
Эксперт по электронике
 Аватар для ФедосеевПавел
8655 / 4490 / 1669
Регистрация: 01.02.2015
Сообщений: 13,898
Записей в блоге: 12
13.05.2018, 17:52
Сначала определить на какой инструкции происходит ошибка. Для этого выполнить по шагам в отладчике x64dbg или ollydbg.

Добавлено через 9 минут
А что за бред в программе?
1. строки 54-65. Начало программы. Какое-то заполнение переменных. Ладно, корректно
2. 67-72. Какие-то push и манипуляции с ebp. Но по всей остальной программе не вижу ни одного ответного pop или sub esp. Т.е. небаланс стека.
3. до строки 108 сложение-умножение
4. 110-117 вывод результата
5. 118 - ret откуда? зачем?

У вас целиком неправильная структура программы. Тут нечего исправлять - только переписывать.

Почитайте методичку, примеры к masm32, примеры на форуме.
2
21 / 21 / 20
Регистрация: 05.12.2017
Сообщений: 124
13.05.2018, 19:55  [ТС]
Спасибо за анализ. Нам сказано делать все по примеру. По этом жалкому примеру и таким вот образом.
Кликните здесь для просмотра всего текста
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
.486                        ;используется набор команд i80486
.model flat, STDCALL        ;модель FLAT, соглашение STDCALL
option casemap:none         ;различать ПРОПИСНЫЕ и строчные
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
.stack 128              ;сегмент стека 128 байт
.data                       ;сегмент данных
A   SWORD   1180h       ;A=0001 0001 1000 0000b=4480d
B   SWORD   2280h       ;B=0010 0010 1000 0000b=8832d 
D   SWORD   1100h       ;D= 0001 0001 0000 0000b=4352d
Y   SWORD ?             ;Y=A+B-D                                           
mD  SWORD ?             ;D=-D 
ApB     SWORD ?             ;ApB=A+B
ApBmD   SWORD ?             ;ApBmD=A+B-D
addrA   DWORD ?             ;адрес А
addrB   DWORD ?             ;адрес В
addrD   DWORD ?             ;адрес D
addrY   DWORD ?             ;адрес Y=A+B-D
addrmD  DWORD ?             ;адрес mD
addrApB     DWORD ?         ;адрес ApB=A+B
addrApBmD   DWORD ?     ;адрес ApBmD=A+B-D
;=======переменные функции MessageBox ================
MsgBoxTitle BYTE "Заголовок MessageBox",0
MsgBoxText  BYTE 128 dup(?),0
;=======строка спецификации формата====================
format1 db "Значение А в 10-й системе A=", "%d","d",0Dh,0Ah,
"Значение А в 16-й сиcтеме А=","%x","h",0Dh,0Ah, 
"Адрес ячейки памяти [А]=","%lx","h",0
;======================================================
.code                       ;сегмент кода
start:                      ;метка начала основной программы
MOV addrD,OFFSET D          ;адрес D  addrD
MOV addrB,OFFSET B          ;адрес B ' addrB
MOV addrA,OFFSET A          ;адрес A ' addrA
MOV addrY,OFFSET Y          ;адрес Y ' addrY
MOV addrmD,OFFSET mD        ;адрес mD ' addrmD
MOV addrApB,OFFSET ApB      ;адрес ApB ' addrApB
MOV addrApBmD,OFFSET ApBmD  ;адрес ApBmD ' addrApBmD
;=======================================
PUSH D                  ;занесение D в стек, [ESP]=[ESP+2]
PUSH B                  ;занесение B в стек, [ESP]=[ESP+2]
PUSH A                  ;занесение A в стек, [ESP]=[ESP+2]
MOV EBP,ESP             ;EBP=ESP для доступа к стеку по EBP
;=======================================
invoke wsprintf, addr MsgBoxText,addr format1, A, A, addrA
invoke MessageBox, 0, ADDR MsgBoxText, ADDR MsgBoxTitle, MB_OK
;=======================================
MOV AX,[EBP]            ;AX=A, А из стека по адресу [EBP]
ADD AX,[EBP+2]      ;AX=AX+B, B из стека по адресу [EBP+2]
MOV ECX,addrApB     ;ECX=addrApB, адрес ApB в [ECX]
MOV [ECX],AX            ;ApB=AX=A+B, адрес ApB в [ECX]
;=======================================
MOV EBX,addrmD          ;EBX=addrmD - адрес mD в [EBX]
MOV DX,[EBP+4]          ;DX=D, D из стека по адресу [EBP+4]
NEG DX                  ;DX=-DX=-D
MOV [EBX],DX            ;mD=DX=-D, адрес mD в [EBX]
;=======================================
SUB AX,[EBP+4]      ;AX=AX-D, D из стека по адресу [EBP+4]
MOV ESI,addrApBmD       ;ESI=addrApBmD, адрес ApBmD в [ESI]
MOV [ESI],AX            ;ApBmD=AX, адрес ApBmD в [ESI]
MOV EDI,addrY           ;EDI= addrY, адрес Y в [EDI]
MOV [EDI],AX            ;Y=AX, адрес Y в [EDI]
invoke ExitProcess, 0   ;API функция завершения процесса
end start               ;конец основной программы

Вставка ret решила ошибку во всех программах, кроме этой.

В общем, вставил invoke ExitProcess, 0 вместо ret и ошибка исправилась.
Павел, спасибо, что уделяете мне время! У меня впереди еще массивы и модульность.
0
Модератор
Эксперт по электронике
 Аватар для ФедосеевПавел
8655 / 4490 / 1669
Регистрация: 01.02.2015
Сообщений: 13,898
Записей в блоге: 12
13.05.2018, 20:19
Лучший ответ Сообщение было отмечено TheDmytrius как решение

Решение

Т.е. вы предлагаете встречный план - мне изучить на основе данного примера структуру программ на ассемблере.

Нет. Я настаиваю на том, чтобы именно вы посмотрели примеры консольных программ на masm (из пакета masm32) и разобрались с ошибкой в структуре.
Примеры в нескольких папках в пакете masm32.
Примеры здесь на форуме во множестве тем.

В общем виде - структура программы на ассемблере мало отличается от таковой на C/C++/Pascal/Delphi: основная программа, процедуры, глобальные переменные.

То, что вы приводите в качестве образца некорректная структура - ищите опечатки или пропуски в методичке.

Почему вы самонадеянно пропускаете обучающие программы HelloWorld? При написании начинает проглядывать структура. Потом только добавляете - процедуры, константы, неинициализированные данные и прочее.

У вас оба кода - бред. Через стек передаются параметры В ПРОЦЕДУРУ. А у вас - main через стек передаёт параметры в main.

Наращивайте функциональность постепенно.
1. программа с расчётом уравнения выражения в основной программе
2. изменение - вычисление в процедуре, передача параметров через глобальные переменные
3. изменение - вычисление в процедуре, передача параметров через стек. можете поначалу воспользоваться автоматизацией от Microsoft - усложнённым синтаксисом proc, а потом и перейти на "рукопашный" стиль.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
13.05.2018, 20:19
Помогаю со студенческими работами здесь

Сохранение данных после закрытия окна
]У меня есть программа в которой есть график, слайдер, кнопка и спинбоксы... суть программы такова: когда начинаю двигать слайдер вправо -...

Глюк скролла после закрытия модального окна
Всем привет. сразу скажу - я нуб. Есть сайт http://katet-arch.ru/, потихоньку пилится. В шапке есть кнопка "перезвоните...

Вылетает программа после закрытия диалогового окна
Есть диалог в котором открывается qwebview header class webViewDialog: public QDialog { Q_OBJECT public: ...

Сбросить форму после закрытия popup окна
Доброго времени суток всем и с наступающими праздниками, такая вот проблема возникла, необходимо после закрытия popup окна сбросить форму,...

Сохранение изменений в таблице после закрытия окна
Мучаю машину уже неделю, а до ума все не доведу... Sql код в запросе работает, но при закрытии формы появляется значок ошибки напротив...


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

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru