Help WinXP завершает мою программу

Низкоуровневое программирование портов, микроконтроллеров и т.д.

Модератор: Andy

Ответить
ichups
Сообщения: 14
Зарегистрирован: 06 июн 2007, 21:57

06 июн 2007, 22:17

код под MASM
в Текстовый документ (3).txt

ошибка происходит при в hextostr при первой попытке записив любой регистр общего назначения
Если её закоментить то всё работает иначе Глюк с предложением отправить сообщение
Вчём дело? ПОМОГИТЕ НАЧИНАЮЩИМ
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Аватара пользователя
somewhere
Сообщения: 1837
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

07 июн 2007, 09:18

Много ошибок стало возникать в связи с тем, что из Ассемблера пытаются сделать язык высокого уровня. Аргументируют сей шаг тем, что якобы разработка программ упрощается, код уменьшается и т.д. Ну раз так, тогда пишите на С, а ассемблер оставьте в покое.
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
ichups
Сообщения: 14
Зарегистрирован: 06 июн 2007, 21:57

07 июн 2007, 18:52

Спасибо Помогло Теперь я всё таки всё отладил (кстати С я действительно знаю несколько лучше но есть ряд вещей которые с помощью С да и др. языков высокого уровнярешить просто невозможно поэтому решил по подробнее познакомиться с Asembler а сразу жить без знакомых вещей сложно )
Ещё вопрос возможно не по теме :а какие ещё подобные баги у masm (mov eax, var это mov eax,[var] или mov eax, offset var или не то и не то или это зависит от случая из предыдущего я понял что mov eax,[var] - это записать в EAX значение которое хранится по адресу на который указывает значение по offset var. так всегда или .....)
Аватара пользователя
somewhere
Сообщения: 1837
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

08 июн 2007, 09:13

&quot писал(а):а какие ещё подобные баги у 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:
и так еще 15 раз, весь блок длиной 18*15 = 270 байт, хотя задача проста - записать представление младшей тетрады по [EAX+EBX] в виде символа.

Код: Выделить всё

mov dl, [eax+ebx]
cmp dl, 0Ah
jc @hex2str_less0A
add dl, 7
    @hex2str_less0A:
add dl, 30h
mov [mesout+ecx], dl
И все... весь громадный блок в 240 байт заменен на этот кусок кода в 11 байт. Никаких .IF .ELSEIF, это прямо BASIC какой-то...
в 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
BBB
Сообщения: 1272
Зарегистрирован: 27 дек 2005, 13:37

08 июн 2007, 09:50

somewhere писал(а): За последние 8 лет я писал программы на обычном TASM без единого макроса...
...отказавшись от многих прелестей макросов...
А макросы-то чем плохи? Или тут имелись в виду не то, что называется ключевым словом macro? Потому как, когда я "баловался" ассемблером, у меня создался наборчик этих макросов, использование которых приносило мне удобство: 1) сокращался объем исходного текста; 2) текст становился более читабельным (так как, вместо, например:

Код: Выделить всё

           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

)
Аватара пользователя
somewhere
Сообщения: 1837
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

08 июн 2007, 10:50

&quot писал(а):1) сокращался объем исходного текста;
Исходного текста, а не полученного кода... Опять же идем к языкам высоко уровня...
Макрос не есть процедура или функция - это блок готового кода, очень часто комбинацию из двух макросов в нормальном виде можно сократить вдвое.
&quot писал(а):2) текст становился более читабельным
Можно делать читабельный код и без макросов, зависит от стиля письма
&quot писал(а):JmpF SaveAddr
Единичный случай, в коде можно встретить раз или два.
It's a long way to the top if you wanna rock'n'roll
ichups
Сообщения: 14
Зарегистрирован: 06 июн 2007, 21:57

08 июн 2007, 21:32

Насчёт кода спасибо была подобная идея но в силу того что хотелось написать хоть что-то работающее так мне показалось проще
А насчёт [] я понимаю что это значит взять по ссылке но что понимается под именем переменной - некоторая константа - адрес хранения или текущее значение или это в зависимости от случаяя и masm сам определяет этот случай
Аватара пользователя
somewhere
Сообщения: 1837
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

09 июн 2007, 11:54

Под именем переменной всегда понимается адрес. Т.е. есть ячейка с адресом, ей присвоили имя. Однако, при работе с переменными компилятор работает со значениями - т.к. судя по человеческой логике нам более важно ЧТО там хранится, а не где это находится. Например:

Код: Выделить всё

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
ichups
Сообщения: 14
Зарегистрирован: 06 июн 2007, 21:57

09 июн 2007, 21:33

Всё ясно thanks а вслучае mov var,eax всё аналогично те
mov [var],eax и
mov var,eax компилируюстся в одно и то же
Ещё мне не понятно как работает div и idiv
это EAX=EAX / оператор или как то иначе более хитро
Да и invoke я использовал (соответственно и masm) потому что по всей моей литературе по Assembler я так и не разобрался на что указывают регистры EBP и ESP
Ответить