Help WinXP завершает мою программу
Модератор: Andy
код под MASM
в Текстовый документ (3).txt
ошибка происходит при в hextostr при первой попытке записив любой регистр общего назначения
Если её закоментить то всё работает иначе Глюк с предложением отправить сообщение
Вчём дело? ПОМОГИТЕ НАЧИНАЮЩИМ
в Текстовый документ (3).txt
ошибка происходит при в hextostr при первой попытке записив любой регистр общего назначения
Если её закоментить то всё работает иначе Глюк с предложением отправить сообщение
Вчём дело? ПОМОГИТЕ НАЧИНАЮЩИМ
- Вложения
-
[Расширение txt было запрещено, вложение больше недоступно.]
Много ошибок стало возникать в связи с тем, что из Ассемблера пытаются сделать язык высокого уровня. Аргументируют сей шаг тем, что якобы разработка программ упрощается, код уменьшается и т.д. Ну раз так, тогда пишите на С, а ассемблер оставьте в покое.
MOV EAX, [variab]
С точки зрения организации параметров в процедуре, переменная variab располагается на стеке. Перед входом в процедуру EBP инициализируется таким образом, что указывает на стек. По сути этой коммандой мы загружаем в ЕАХ значение, которое находится по смещению, которое записано на стеке. Никто не видит, но на самом деле там две комманды:
MOV EAX, [EBP+XXXX] ; адрес variab на стеке
MOV EAX, [EAX] ; загрузка значения
при передаче параметров через INVOKE - часть невидимого кода содержит
PUSH MyVar ; не иначе как передача значения, а не ссылки
В итоге передаем значение, и используем его потом как ссылку. А что у нас процессор делает, когда мы лезем в ту область памяти, куда не надо? правильно, дает по башке на аппаратном уровне, используя механизм защиты и выработки исключений.
Вот из-за того, что существует код, который не виден я и не пишу на MASM и вам не советую, если не хотите сидеть в отладке несколько месяцев. Нет в процессоре комманд .IF, .ELSEIF, INVOKE и т.д. Все должно быть как на ладони, а не как в ж... - извиняюсь за мой французский :-)
MOV EAX, [variab]
С точки зрения организации параметров в процедуре, переменная variab располагается на стеке. Перед входом в процедуру EBP инициализируется таким образом, что указывает на стек. По сути этой коммандой мы загружаем в ЕАХ значение, которое находится по смещению, которое записано на стеке. Никто не видит, но на самом деле там две комманды:
MOV EAX, [EBP+XXXX] ; адрес variab на стеке
MOV EAX, [EAX] ; загрузка значения
при передаче параметров через INVOKE - часть невидимого кода содержит
PUSH MyVar ; не иначе как передача значения, а не ссылки
В итоге передаем значение, и используем его потом как ссылку. А что у нас процессор делает, когда мы лезем в ту область памяти, куда не надо? правильно, дает по башке на аппаратном уровне, используя механизм защиты и выработки исключений.
Вот из-за того, что существует код, который не виден я и не пишу на MASM и вам не советую, если не хотите сидеть в отладке несколько месяцев. Нет в процессоре комманд .IF, .ELSEIF, INVOKE и т.д. Все должно быть как на ладони, а не как в ж... - извиняюсь за мой французский :-)
It's a long way to the top if you wanna rock'n'roll
Спасибо Помогло Теперь я всё таки всё отладил (кстати С я действительно знаю несколько лучше но есть ряд вещей которые с помощью С да и др. языков высокого уровнярешить просто невозможно поэтому решил по подробнее познакомиться с Asembler а сразу жить без знакомых вещей сложно )
Ещё вопрос возможно не по теме :а какие ещё подобные баги у masm (mov eax, var это mov eax,[var] или mov eax, offset var или не то и не то или это зависит от случая из предыдущего я понял что mov eax,[var] - это записать в EAX значение которое хранится по адресу на который указывает значение по offset var. так всегда или .....)
Ещё вопрос возможно не по теме :а какие ещё подобные баги у masm (mov eax, var это mov eax,[var] или mov eax, offset var или не то и не то или это зависит от случая из предыдущего я понял что mov eax,[var] - это записать в EAX значение которое хранится по адресу на который указывает значение по offset var. так всегда или .....)
В MASM это не баг - это способ доступа к параметрам. Для того, чтобы не запутатся нужно просто понимать, как это все работает, т.е. что скрывается за каждой командой... Квадратные скобки всегда означают "взять по ссылке", здесь сложности нет никакой." писал(а):а какие ещё подобные баги у masm
Вообще сам MASM - один большой баг - попытка свести язык низкого уровня к более высокому. В результате введения макроопределений вроде .IF объем кода увеличился и скорость работы упала в разы. За последние 8 лет я писал программы на обычном TASM без единого макроса - и я уже начал забывать что такое отладка в языке ассемблера. Имея свою собственную структуру оформления кода и достаточный объем оптимизирванных процедур для разного рода задач составление программ стало одним удовольствием. Я не имел ввиду - "не пишите на MASM(TASM)" - просто отказавшись от многих прелестей макросов вы повысите не только профессиональный уровень, но и качество, красоту своей программы.
Давайте подумаем что можно сделать с этим страшным куском кода:
Он состоит из наборов.IF eax==1
mov [mesout+ecx],'1'
.ELSEIF BYTE PTR[eax+ebx]==2
mov [mesout+ecx],'2'
.ELSEIF BYTE PTR[eax+ebx]==3
mov [mesout+ecx],'3'
.ELSEIF BYTE PTR[eax+ebx]==4
mov [mesout+ecx],'4'
.ELSEIF BYTE PTR[eax+ebx]==5
mov [mesout+ecx],'5'
.ELSEIF BYTE PTR[eax+ebx]==6
mov [mesout+ecx],'6'
.ELSEIF BYTE PTR[eax+ebx]==7
mov [mesout+ecx],'7'
.ELSEIF BYTE PTR[eax+ebx]==8
mov [mesout+ecx],'8'
.ELSEIF BYTE PTR[eax+ebx]==9
mov [mesout+ecx],'9'
.ELSEIF BYTE PTR[eax+ebx]==0Ah
mov [mesout+ecx],'A'
.ELSEIF BYTE PTR[eax+ebx]==0Bh
mov [mesout+ecx],'B'
.ELSEIF BYTE PTR[eax+ebx]==0Ch
mov [mesout+ecx],'C'
.ELSEIF BYTE PTR[eax+ebx]==0Dh
mov [mesout+ecx],'D'
.ELSEIF BYTE PTR[eax+ebx]==0Eh
mov [mesout+ecx],'E'
.ELSEIF BYTE PTR[eax+ebx]==0Fh
mov [mesout+ecx],'F'
.ELSEIF BYTE PTR[eax+ebx]==0h
mov [mesout+ecx],'0'
.ENDIF
Код: Выделить всё
CMP BYTE PTR [eax+ebx], XX
JNZ @LABEL1
MOV BYTE PTR [ecx+const32], XX
JMP SHORT @LABEL_EXIT
@LABEL1:
....
@LABEL_EXIT:
Код: Выделить всё
mov dl, [eax+ebx]
cmp dl, 0Ah
jc @hex2str_less0A
add dl, 7
@hex2str_less0A:
add dl, 30h
mov [mesout+ecx], dl
в DL загружаем младшую тетраду. Если она больше 10 (0А), то добавить к ней 7. Потом в любом случае добавить 48 (30h).
Код символа '0' - 30h, т.е. если число меньше 10 - переведем из числа в цифру. Если больше 10, то попадем на символ. Например, в DL = 11 (0Bh) - это больше 10, добавляем 7 (18), и еще добавляем 48 (66). 66 (42h) - код символа 'B'
It's a long way to the top if you wanna rock'n'roll
А макросы-то чем плохи? Или тут имелись в виду не то, что называется ключевым словом macro? Потому как, когда я "баловался" ассемблером, у меня создался наборчик этих макросов, использование которых приносило мне удобство: 1) сокращался объем исходного текста; 2) текст становился более читабельным (так как, вместо, например:somewhere писал(а): За последние 8 лет я писал программы на обычном TASM без единого макроса...
...отказавшись от многих прелестей макросов...
Код: Выделить всё
db 0EAh ; Far jump to ...
Memory dd (?) ; ... Memory
JmpF SaveAddr
а JmpF определялось как:
Код: Выделить всё
JmpF Macro Memory
;; Far jump to address
;; Registers cdhanged: none
db 0EAh ; Far jump to ...
Memory dd (?) ; ... Memory
EndM
)
Исходного текста, а не полученного кода... Опять же идем к языкам высоко уровня..." писал(а):1) сокращался объем исходного текста;
Макрос не есть процедура или функция - это блок готового кода, очень часто комбинацию из двух макросов в нормальном виде можно сократить вдвое.
Можно делать читабельный код и без макросов, зависит от стиля письма" писал(а):2) текст становился более читабельным
Единичный случай, в коде можно встретить раз или два." писал(а):JmpF SaveAddr
It's a long way to the top if you wanna rock'n'roll
Насчёт кода спасибо была подобная идея но в силу того что хотелось написать хоть что-то работающее так мне показалось проще
А насчёт [] я понимаю что это значит взять по ссылке но что понимается под именем переменной - некоторая константа - адрес хранения или текущее значение или это в зависимости от случаяя и masm сам определяет этот случай
А насчёт [] я понимаю что это значит взять по ссылке но что понимается под именем переменной - некоторая константа - адрес хранения или текущее значение или это в зависимости от случаяя и masm сам определяет этот случай
Под именем переменной всегда понимается адрес. Т.е. есть ячейка с адресом, ей присвоили имя. Однако, при работе с переменными компилятор работает со значениями - т.к. судя по человеческой логике нам более важно ЧТО там хранится, а не где это находится. Например:
Последний случай рассматривается как две команды в зависмости от компилятора. Вообще ничем не отличается от первого.
Код: Выделить всё
var dw 10h ; Перем. var содержит число 10h, и допустим, находится по смещению 18h
...
mov eax, var ; mov eax, [00000018h] ; eax = 00000010h
mov eax, offset var ; mov eax, 00000018h ; eax = 00000018h
mov eax, [var] ; mov eax, [00000018h]
; mov eax, [eax] ; eax = ????????h
It's a long way to the top if you wanna rock'n'roll
Всё ясно thanks а вслучае mov var,eax всё аналогично те
mov [var],eax и
mov var,eax компилируюстся в одно и то же
Ещё мне не понятно как работает div и idiv
это EAX=EAX / оператор или как то иначе более хитро
Да и invoke я использовал (соответственно и masm) потому что по всей моей литературе по Assembler я так и не разобрался на что указывают регистры EBP и ESP
mov [var],eax и
mov var,eax компилируюстся в одно и то же
Ещё мне не понятно как работает div и idiv
это EAX=EAX / оператор или как то иначе более хитро
Да и invoke я использовал (соответственно и masm) потому что по всей моей литературе по Assembler я так и не разобрался на что указывают регистры EBP и ESP