|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Апр 8, 2004 19:01:09 S_T_A_S_ Вот блин, не обратил внимание, привычка с masm32 так писать ;-) Спасибо. |
|
|
Дата: Апр 8, 2004 22:37:50 Продолжаем.. Пытаюсь вызвать СВОЮ процедуру резонно предполагая что должен делать это так: stdcall GetClipboardText Получаю: Error: invalid operand. Instruction: pushd Почему? |
|
|
Дата: Апр 9, 2004 04:37:12 Если аргументы передавать не предполагается используйте просто call. Или внесите изменения в макрос stdcall: { common if ~ arg eq reverse pushd arg common call [proc] else call [proc] end if } |
|
|
Дата: Апр 9, 2004 05:11:19 pas Так и поступил, но почему Privalov макрос не поправит? |
|
|
Дата: Апр 9, 2004 09:54:12 Asterix Privalov придерживается принципа простоты - что-бы можно было разобраться проще, научиться по его макросам. У меня invoke может иметь хоть сколько параметров, причем есть проверка кол-ва аргументов. Вызывает хоть свою proc, хоть импортируемую из dll - автоматом определяется тип call. Для оптимизации можно использовать stdcall/call. |
|
|
Дата: Апр 10, 2004 18:43:51 S_T_A_S_ Кстати, хороший философский вопрос: надо ли 'маскировать' все типы вызовов как один? Например: call foo imp_call foo1 Здесь, сразу ясно, где вызов функции импортитуемой и где - обычной. С точки зрения сопровождаемости кода - более читабельно. |
|
|
Дата: Апр 10, 2004 20:35:58 AsmGuru62 Да, вопрос действительно филосовский.. AFAIK, TASM делает CALL на JMP, который в свою очередь вызывает ф-цию в dll (?) (хотя сам не смотрел - не пользовался) MASM по умолчанию - так же ^^, но многие пользуют "альтернативный вариант" - CALL [imp_foo] - для экономии места. Причем INVOKE в MASM скрывает тип вызова (прямой или косвенный через Lockup Table) автоматически. В FASM "высокоуровнывых" вызовов (INVOKE, CALL как в TASM) нет. Все это делается макросами. В стандартной поставке есть stdcall - засовывает параметры в стек и делает вызов. Т.е. импортируемая ф-ция вызывается так: stdcall [ExitProcess],0 (через Lockup Table) Еще есть: invoke ExitProcess,0 (т.е. здесь вызывается indirect stdcall, и для обычных ф-ций не подходит. По причине упомянутой pas, а так же некоторым другим, многие пишут свои макросы для FASM. Так что тут полный бардак :) Даже между разными ассемблерами. По поводу читабельности кода я пока придерживаюсь правила начинать имя ф-ции со слова соответствующего имени файла (модуля) где она объявлена. Возможно не самый лучший вариант, IMHO так ее проще искать и избегать конфликтов имен. У меня, например, не так много импортируемых функций и все они из winAPI. (т.е. имена хорошо известны) Так что я даже не задумывался о том, надо ли их различать (до этого момента :) |
|
|
Дата: Апр 10, 2004 21:40:22 · Поправил: Asterix Продолжаем... Есть у меня такая процедура: ScanString proc lpszString:DWORD
option PROLOGUE:NONE
option EPILOGUE:NONE
push ecx
push esi
mov esi, [esp+0Ch]
mov ecx, 8
cld
ALIGN DWORD
@@:
lodsb
test al, al
jz @F
.IF (al>="0" && al<="9") || (al>="A" && al<="F") || (al>="a" && al<="f")
.IF al>="a" && al<="f"
sub al, 20h
mov BYTE PTR [esi-01h], al
.ENDIF
loop @B
mov BYTE PTR [esi], 0
@@:
mov eax, [esp+0Ch]
jmp @F
.ENDIF
xor eax, eax
@@:
pop esi
pop ecx
ret (sizeof DWORD)
option PROLOGUE:PROLOGUEDEF
option EPILOGUE:EPILOGUEDEF
ScanString endp
Нужно было переделать под fasm, посмотрел и увидел что у fasm'а есть какие-то макросы .if/.endif, но как оказалось они настолько не совершенны что воспользоваться ими не получилось.. Не придумал ничего лучше чем вырипать свою же собственную процедуру в IDA, но естественно в этой процедуре образовалось множество меток, коим я так и не смог придумать логические названия(не всем, некоторые всё же обозвал ;-) Всё-таки в плане макросов masm32 велик.. Ладно думаю, переписал процедуру по другому, количество прыжков уменьшилось и меток соответственно тоже, но почему-то увеличилось количество тактов :-( она стала выглядеть так: ScanString:
push ecx
push esi
mov esi, [esp+0Ch]
mov ecx, 8
cld
ALIGN 4
@@:
lodsb
test al, al
jz @F
cmp al, 'f'+1
sbb ebx, ebx
cmp al, 'a'
adc ebx, 0
jnz .found
cmp al, 'F'+1
sbb ebx, ebx
cmp al, 'A'
adc ebx, 0
cmp al, '9'+1
sbb ebx, 0
cmp al, '0'
adc ebx, 0
and eax, ebx
jz .ret
jmp .loop
.found:
sub al, 20h
mov BYTE [esi-01h], al
.loop:
loop @B
mov BYTE [esi], 0
@@:
mov eax, [esp+0Ch]
.ret:
pop esi
pop ecx
ret 4
Это оказалось медленнее.. Кто-нибудь может меня убедить что fasm мощен своими макро возможностями?? |
|
|
Дата: Апр 10, 2004 22:49:50 · Поправил: S_T_A_S_ Asterix Вот это: .IF (al>="0" && al<="9") || (al>="A" && al<="F") на асме можно сделать примерно так: mov cl, al sub cl, 2F ;; 0123456789:;<=>?@ABCDEFGHIJKLMNO mov eax, 11111111110000000111111000000000b shl eax, cl jc .hexnumber Я тут возможно ошибся, но идея думаю понятна. Так что .IF / .ELSE не очень полезная вещь ;-) ЗЫ В MASM макросы есть сразу. А FASMе их нужно написать, но написать-то можно хоть что ;-) |
|
|
Дата: Апр 11, 2004 03:08:10 Asterix ScanString:
mov eax,[esp+4]
movq mm0,[eax]
movq mm1,mm0
pcmpgtb mm1,qword [.a]
pand mm1,qword [.d]
psubb mm0,mm1
movq mm1,mm0
pcmpgtb mm1,qword [.z]
movq mm2,mm0
pcmpgtb mm2,qword [.n]
pxor mm1,mm2
movq mm2,mm0
pcmpgtb mm2,qword [.A]
pxor mm1,mm2
movq mm2,mm0
pcmpgtb mm2,qword [.F]
pxor mm1,mm2
pand mm0,mm1
movq [eax],mm0
mov byte [eax+8],0
ret 4
.a db 60h,60h,60h,60h,60h,60h,60h,60h
.d db 20h,20h,20h,20h,20h,20h,20h,20h
.z db 2Fh,2Fh,2Fh,2Fh,2Fh,2Fh,2Fh,2Fh
.n db 39h,39h,39h,39h,39h,39h,39h,39h
.A db 40h,40h,40h,40h,40h,40h,40h,40h
.F db 46h,46h,46h,46h,46h,46h,46h,46h
Не нужны здесь никакие макросы! |
|
|
Дата: Апр 11, 2004 04:15:13 Black_mirror Спасибо! :-) Не нужны здесь никакие макросы! Зато нужон MMX ;-) |
|
|
Дата: Апр 11, 2004 04:25:01 Привет. Етот проблем (ScanString) илюстрирует очень хорошо одну из моих теории, что изпользование HLL конструкции как if/else/while/ в ассемблере просто мешает програмисту увидеть красивые и естественые решения. (ето относиться и к stdcall/invoke тоже но в меньшей мере - здесь предимства больше чем недостатков) |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.067 |