· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.ASSEMBLER —› Макросы в fasm.

<< . 1 . 2 .

Посл.отвђт Сообщен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 тоже но в меньшей мере - здесь предимства больше чем недостатков)

<< . 1 . 2 .


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.067