Author Topic: Using proto typedefs in HLL  (Read 428 times)

nidud

  • Member
  • *****
  • Posts: 1359
    • https://github.com/nidud/asmc
Using proto typedefs in HLL
« on: January 25, 2017, 05:31:45 AM »
Code: [Select]
PROTO_T TYPEDEF PROTO STDCALL :DWORD, :DWORD
PROTO_P TYPEDEF PTR PROTO_T

Using pointers works in INVOKE but failed in HLL:
Code: [Select]
.data
data_p PROTO_P 0

.code

invoke data_p,1,2

.if data_p(1,2) ; failed..

nop
.endif

Same using stack:
Code: [Select]
foo proc stack_p:PROTO_P

invoke stack_p,1,2

.if stack_p(1,2) ; failed..

nop
.endif

foo endp

jj2007

  • Member
  • *****
  • Posts: 7470
  • Assembler is fun ;-)
    • MasmBasic
Re: Using proto typedefs in HLL
« Reply #1 on: January 25, 2017, 08:05:27 AM »
.if   data_p(1,2)   ; failed..

.if   rv(data_p, 1,2)   ; works..

nidud

  • Member
  • *****
  • Posts: 1359
    • https://github.com/nidud/asmc
Re: Using proto typedefs in HLL
« Reply #2 on: January 25, 2017, 09:04:46 AM »
test case:
Code: [Select]
.486
.model flat, stdcall
.code

PROTO_T TYPEDEF PROTO STDCALL :DWORD, :DWORD
PROTO_P TYPEDEF PTR PROTO_T

.data
data_p PROTO_P 0

.code

.if data_p(1,2) > 0

nop
.endif

.ifb data_p(1,2) > 0

nop
.endif

.ifs eax > edx

nop
.endif

.ifs data_p(1,2) > 0

nop
.endif

END

output:
Code: [Select]
00000000                        .if data_p(1,2) > 0
00000000                    *   invoke data_p, 1, 2
00000000  6A02              *    push 2
00000002  6A01              *    push 1
00000004  FF1500000000      *    call data_p
0000000A  83F800            *   cmp eax , 0
0000000D  7601              *   jna @C0001

0000000F  90                    nop
00000010                        .endif
00000010                    *   @C0001:

00000010                        .ifb data_p(1,2) > 0
00000010                    *   invoke data_p, 1, 2
00000010  6A02              *    push 2
00000012  6A01              *    push 1
00000014  FF1500000000      *    call data_p
0000001A  3C00              *   cmp   al, 0
0000001C  7601              *   jna @C0002

0000001E  90                    nop
0000001F                        .endif
0000001F                    *   @C0002:

0000001F                        .ifs eax > edx
0000001F  3BC2              *   cmp eax , edx
00000021  7E01              *   jng @C0003

00000023  90                    nop
00000024                        .endif
00000024                    *   @C0003:

00000024                        .ifs data_p(1,2) > 0
00000024                    *   invoke data_p, 1, 2
00000024  6A02              *    push 2
00000026  6A01              *    push 1
00000028  FF1500000000      *    call data_p
0000002E  83F800            *   cmp eax , 0
00000031  7E01              *   jng @C0004

00000033  90                    nop
00000034                        .endif
00000034                    *   @C0004:

.IFS - Signed compare added
.IFB and .IFW extended to 32-bit and .IFB to 16-bit

.IFBS, .IFWS, .IFDS...

nidud

  • Member
  • *****
  • Posts: 1359
    • https://github.com/nidud/asmc
Re: Using proto typedefs in HLL
« Reply #3 on: March 02, 2017, 06:58:15 AM »
These proto types are useful in windows.inc to make compatible functions based on version compiled.

Declearation (winbase.inc):
Code: [Select]
if (WINVER GE 0x0502)
;BOOL
SetFilePointerEx proto _CType \
hFile: HANDLE,
      liDistanceToMove: LARGE_INTEGER,
      lpNewFilePointer: PLARGE_INTEGER,
  dwMoveMethod: DWORD
else
SetFilePointerEx_P typedef proto _CType \
hFile: HANDLE,
      liDistanceToMove: LARGE_INTEGER,
      lpNewFilePointer: PLARGE_INTEGER,
  dwMoveMethod: DWORD
SetFilePointerEx_T typedef ptr SetFilePointerEx_P
externdef SetFilePointerEx:SetFilePointerEx_T
endif

Implement:
Code: [Select]

if (WINVER LT 0x0502)

.data
externdef kernel32_dll:BYTE
SetFilePointerEx SetFilePointerEx_T dummy
.code

dummy proc _CType private \
hFile: HANDLE,
      liDistanceToMove: LARGE_INTEGER,
      lpNewFilePointer: PLARGE_INTEGER,
  dwMoveMethod: DWORD

mov eax,DWORD PTR liDistanceToMove
mov edx,DWORD PTR liDistanceToMove[4]
mov ecx,lpNewFilePointer
add ecx,4
mov [ecx],edx

.if SetFilePointer(
hFile, ;; handle of file
eax, ;; number of bytes to move file pointer
ecx, ;; pointer to high-order DWORD of distance to move
dwMoveMethod ) ;; how to move

mov edx,lpNewFilePointer
mov [edx],eax
mov eax,1
.endif
ret

dummy endp

Install:
.if GetModuleHandle( addr kernel32_dll )

.if GetProcAddress( eax, "SetFilePointerEx" )

mov SetFilePointerEx,eax
.endif
.endif
ret

pragma_init Install,7

endif

Usage:
Code: [Select]
_lseeki64 PROC handle:SINT, offs:QWORD, pos:DWORD

local lpNewFilePointer:QWORD

.if getosfhnd( handle ) != -1

mov ecx,eax
lea eax,lpNewFilePointer

.if !SetFilePointerEx( ecx, offs, eax, pos )

mov edx,osmaperr()
.else
mov eax,DWORD PTR lpNewFilePointer
mov edx,DWORD PTR lpNewFilePointer[4]
.endif
.else
mov edx,eax
.endif
ret
_lseeki64 ENDP

nidud

  • Member
  • *****
  • Posts: 1359
    • https://github.com/nidud/asmc
Re: Using proto typedefs in HLL
« Reply #4 on: March 02, 2017, 08:42:27 AM »
Looking at the SetFilePointer() example above the function actually return INVALID_SET_FILE_POINTER (-1) on error and not 0.  The (hopefully   :biggrin:) correct implementation should then be something like this:
Code: [Select]
.if SetFilePointer(
hFile, ;; handle of file
eax, ;; number of bytes to move file pointer
ecx, ;; pointer to high-order DWORD of distance to move
dwMoveMethod ) != -1 ;; how to move

mov edx,lpNewFilePointer
mov [edx],eax
mov eax,1
.else
dec eax
.endif