somewhere » 08 июн 2007, 09:13
" писал(а):а какие ещё подобные баги у 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'
[quote="""]а какие ещё подобные баги у masm [/quote]
В MASM это не баг - это способ доступа к параметрам. Для того, чтобы не запутатся нужно просто понимать, как это все работает, т.е. что скрывается за каждой командой... Квадратные скобки всегда означают "взять по ссылке", здесь сложности нет никакой.
Вообще сам MASM - один большой баг - попытка свести язык низкого уровня к более высокому. В результате введения макроопределений вроде .IF объем кода увеличился и скорость работы упала в разы. За последние 8 лет я писал программы на обычном TASM без единого макроса - и я уже начал забывать что такое отладка в языке ассемблера. Имея свою собственную структуру оформления кода и достаточный объем оптимизирванных процедур для разного рода задач составление программ стало одним удовольствием. Я не имел ввиду - "не пишите на MASM(TASM)" - просто отказавшись от многих прелестей макросов вы повысите не только профессиональный уровень, но и качество, красоту своей программы.
Давайте подумаем что можно сделать с этим страшным куском кода:
[quote]
.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
[/quote]
Он состоит из наборов
[code]
CMP BYTE PTR [eax+ebx], XX
JNZ @LABEL1
MOV BYTE PTR [ecx+const32], XX
JMP SHORT @LABEL_EXIT
@LABEL1:
....
@LABEL_EXIT:
[/code]
и так еще 15 раз, весь блок длиной 18*15 = 270 байт, хотя задача проста - записать представление младшей тетрады по [EAX+EBX] в виде символа.
[code]
mov dl, [eax+ebx]
cmp dl, 0Ah
jc @hex2str_less0A
add dl, 7
@hex2str_less0A:
add dl, 30h
mov [mesout+ecx], dl
[/code]
И все... весь громадный блок в 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'