flat assembler
Message board for the users of flat assembler.

Index > Main > DEFINITE operator in fasm 1.73.11 and fasm g.iiviv

Author
Thread Post new topic Reply to topic
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8349
Location: Kraków, Poland
Tomasz Grysztar 20 Apr 2019, 11:22
The yesterday's releases bring a long-overdue feature: a variant of DEFINED operator that only checks whether symbol has been defined earlier in the source (that is: if it has already been properly defined in the current pass, during the multi-pass assembly).

The new operator is called DEFINITE. It can be interpreted as meaning that all symbols within a given expression have definitely been defined - they all have had values assigned already before the current position. This is different from DEFINED which can predict that symbol is going to be defined later (based on the knowledge gathered from the previous passes).

The obvious use case case is this idiom, which could not be done with fasm's classic DEFINED operator without additional tricks (like forcing use of variable symbol, or even using an additional flag to get rid of self-contradiction):
Code:
if ~ definite Module
    Module = 1 ; define only if it has not already been defined earlier
end if    

It was perhaps because of various tricks that allowed to use DEFINED for a similar purpose, that this feature was left unimplemented until now. But I found that it has other uses where DEFINED cannot replace it. Sometimes you may really need to know whether a label passed to your macro is defined before or after in the source. I may write more about that soon, as a continuation of my article about multi-pass.

Keep in mind: DEFINITE only guarantees that a symbol has been defined somewhere earlier in the source. It does not mean that the value of the symbol is final and resolved. The latter is impossible to know for sure in an assembler like fasm. Consider a simple example:
Code:
if used Module
    ModuleState = 1
else
    ModuleState = 0
end if
; ...
if definite ModuleState    
While here DEFINITE is always going to tell that "ModuleState" has already been defined, the actual value of "ModuleState" may be in flux, as things that happen even later in source may affect the outcome. And a web of dependencies in the assembly may be much more complex and unpredictable than in this simplified sample.
Post 20 Apr 2019, 11:22
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20299
Location: In your JS exploiting you and your system
revolution 20 Apr 2019, 12:43
I definitely like it. Smile
Post 20 Apr 2019, 12:43
View user's profile Send private message Visit poster's website Reply with quote
guignol



Joined: 06 Dec 2008
Posts: 763
guignol 21 Apr 2019, 12:44
and what is wrong with RECK ?
Post 21 Apr 2019, 12:44
View user's profile Send private message Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 798
Location: Russian Federation, Sochi
ProMiNick 22 Apr 2019, 12:07
revolution, thou "definitely like it", but in fasmarm still
patch negation_ok, <je check_for_used>, <call ARM_check_processor,nop>, 29
while for definite should be
patch negation_ok, <je check_for_used>, <call ARM_check_processor,nop>, 37

and no definite between defined & dup in table.
or thou gave up to maintaining fasmarm?
Post 22 Apr 2019, 12:07
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20299
Location: In your JS exploiting you and your system
revolution 22 Apr 2019, 12:13
Okay, thanks for the new patch value.

Right now I am unable to access. I will update it later when I am back.
Post 22 Apr 2019, 12:13
View user's profile Send private message Visit poster's website Reply with quote
guignol



Joined: 06 Dec 2008
Posts: 763
guignol 22 Apr 2019, 19:39
Laughing

better yet, thou is reserved for friends
Post 22 Apr 2019, 19:39
View user's profile Send private message Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 798
Location: Russian Federation, Sochi
ProMiNick 22 Apr 2019, 23:34
And one more revolution:
if thou going to update fasmarm
in fasmarm_full.zip
in folder source still missed DLL subfolder with FASMARM.ASM file with content...
...something like that:
Code:
; flat assembler DLL interface for Win32
; Copyright (c) 1999-2019, Tomasz Grysztar.
; All rights reserved.

format PE DLL GUI 4.0
entry DLLEntryPoint

include 'win32a.inc'
include 'fasm.ash'

section '.data' data readable writeable

mutex dd ?
state dd ?
esp_save dd ?
source dd ?
source_position dd ?
first_write dd ?
first_write_length dd ?
second_write dd ?
second_write_length dd ?
display_pipe dd ?

systime SYSTEMTIME

tmp dd ?
buffer rb 1000h

include '..\variable.inc'

section '.text' code readable executable

DLLEntryPoint:

  virtual at esp+4
    hinstDLL dd ?
    fdwReason dd ?
    lpvReserved dd ?
  end virtual

        cmp     [fdwReason],DLL_PROCESS_ATTACH
        jne     dll_ok
        cmp     [mutex],0
        jne     dll_ok
        invoke  CreateMutex,NULL,FALSE,NULL
        mov     [mutex],eax
        test    eax,eax
        jz      dll_failed
    dll_ok:
        mov     eax,TRUE
        ret     12
    dll_failed:
        mov     eax,FALSE
        ret     12

VERSION_MAJOR = 1
VERSION_MINOR = 43
fasm_GetVersion:
        mov     eax,VERSION_MAJOR + VERSION_MINOR shl 16
        ret

fasm_AssembleFile:

        invoke  WaitForSingleObject,[mutex],-1

        mov     eax,[lpSource]
        mov     [input_file],eax
        mov     [output_file],null_byte

        jmp     setup_assembler

fasm_Assemble:

  virtual at esp+4
    lpSource dd ?
    lpMemory dd ?
    cbMemorySize dd ?
    nPassesLimit dd ?
    hDisplayPipe dd ?
  end virtual

        invoke  WaitForSingleObject,[mutex],-1

        mov     eax,[lpSource]
        mov     [source],eax
        mov     [source_position],0

        mov     [input_file],null_byte
        mov     [output_file],null_byte

  setup_assembler:

        mov     eax,[nPassesLimit]
        cmp     eax,10000h
        ja      invalid_parameter
        or      eax,eax
        jz      invalid_parameter
        mov     [passes_limit],ax

        mov     eax,[lpMemory]
        mov     ecx,[cbMemorySize]
        mov     [state],eax
        mov     [eax+FASM_STATE.condition],FASM_WORKING
        sub     ecx,sizeof.FASM_STATE
        jbe     out_of_memory
        add     eax,sizeof.FASM_STATE
        mov     [memory_start],eax
        mov     edx,ecx
        shr     edx,2
        sub     ecx,edx
        add     eax,ecx
        mov     [memory_end],eax
        mov     [additional_memory],eax
        add     eax,edx
        mov     [additional_memory_end],eax

        xor     eax,eax
        mov     [initial_definitions],eax

        mov     [first_write],eax
        mov     [second_write],eax

        mov     eax,[hDisplayPipe]
        mov     [display_pipe],eax

        push    ebp ebx esi edi
        mov     eax,esp
        mov     [esp_save],eax
        and     eax,not 0FFFh
        add     eax,1000h-10000h
        mov     [stack_limit],eax

        call    preprocessor
        call    parser
        call    assembler
        call    formatter

        mov     ebx,[state]
        mov     [ebx+FASM_STATE.condition],FASM_OK

  done:
        invoke  ReleaseMutex,[mutex]
        mov     eax,[ebx+FASM_STATE.condition]
        pop     edi esi ebx ebp
        ret     20

  invalid_parameter:
        mov     [state],buffer
        mov     eax,FASM_INVALID_PARAMETER

  general_error:
        mov     esp,[esp_save]
        mov     ebx,[state]
        mov     [ebx+FASM_STATE.condition],eax
        jmp     done

  assembler_error:
        mov     esp,[esp_save]
        mov     ebx,[state]
        mov     [ebx+FASM_STATE.error_code],eax
        mov     eax,[current_line]
        mov     [ebx+FASM_STATE.error_line],eax
        mov     eax,FASM_ERROR
        jmp     general_error

  get_environment_variable:
        mov     ecx,[memory_end]
        sub     ecx,edi
        invoke  GetEnvironmentVariable,esi,edi,ecx
        add     edi,eax
        ret

  open:
        cmp     byte [edx],0
        je      open_memory
        invoke  CreateFile,edx,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0
        cmp     eax,-1
        je      file_error
        mov     ebx,eax
        clc
        retn
    file_error:
        stc
        retn
    open_memory:
        xor     ebx,ebx
        retn
  read:
        or      ebx,ebx
        jz      read_memory
        mov     ebp,ecx
        invoke  ReadFile,ebx,edx,ecx,tmp,0
        or      eax,eax
        jz      file_error
        cmp     ebp,[tmp]
        jne     file_error
        clc
        retn
    read_memory:
        push    esi edi
        mov     esi,[source]
        add     esi,[source_position]
        mov     edi,edx
        call    move_block
        pop     edi esi
        clc
        retn
    move_block:
        mov     al,cl
        shr     ecx,2
        rep     movsd
        mov     cl,al
        and     cl,11b
        rep     movsb
        retn
  lseek:
        or      ebx,ebx
        jz      seek_memory
        movzx   eax,al
        invoke  SetFilePointer,ebx,edx,0,eax
        cmp     eax,-1
        je      file_error
        retn
    seek_memory:
        push    esi
        mov     esi,[source]
        mov     ecx,edx
        or      al,al
        jz      seek_forward
        add     esi,[source_position]
        cmp     al,2
        je      seek_source_end
    seek_forward:
        sub     ecx,1
        jc      seek_complete
    seek_in_source:
        lodsb
        or      al,al
        loopnz  seek_in_source
        jnz     seek_complete
        dec     esi
    seek_complete:
        mov     eax,esi
        sub     eax,[source]
        mov     [source_position],eax
        pop     esi
        retn
    seek_source_end:
        lodsb
        or      al,al
        jnz     seek_source_end
        dec     esi
        sub     esi,edx
        cmp     esi,[source]
        jae     seek_complete
        mov     esi,[source]
        jmp     seek_complete
  create:
        or      ebx,-1
        clc
        retn
  write:
        cmp     [first_write],0
        jne     make_second_write
        mov     [first_write],edx
        mov     [first_write_length],ecx
        clc
        retn
    make_second_write:
        cmp     [second_write],0
        jne     cannot_write
        mov     [second_write],edx
        mov     [second_write_length],ecx
        clc
        retn
    cannot_write:
        stc
        retn
  close:
        or      ebx,ebx
        jz      file_closed
        cmp     ebx,-1
        je      output_ready
        invoke  CloseHandle,ebx
    file_closed:
        retn
    output_ready:
        mov     ebx,[state]
        cmp     [second_write],0
        jne     two_part_output
        mov     eax,[first_write]
        mov     [ebx+FASM_STATE.output_data],eax
        mov     eax,[first_write_length]
        mov     [ebx+FASM_STATE.output_length],eax
        retn
    two_part_output:
        mov     eax,[second_write]
        mov     [ebx+FASM_STATE.output_data],eax
    shuffle_output:
        mov     ecx,[first_write_length]
        cmp     ecx,[second_write_length]
        ja      small_second_part
        sub     [second_write_length],ecx
        mov     esi,[first_write]
        mov     edi,[second_write]
        call    xchg_block
        mov     [second_write],edi
        jmp     shuffle_output
    xchg_block:
        shr     ecx,1
        jnc     xchgb_ok
        mov     al,[edi]
        xchg    al,[esi]
        stosb
        inc     esi
      xchgb_ok:
        shr     ecx,1
        jnc     xchgw_ok
        mov     ax,[edi]
        xchg    ax,[esi]
        stosw
        add     esi,2
      xchgw_ok:
        jz      xchgd_ok
      xchgd:
        mov     eax,[edi]
        xchg    eax,[esi]
        stosd
        add     esi,4
        loop    xchgd
      xchgd_ok:
        retn
    small_second_part:
        mov     edi,[second_write]
        mov     esi,edi
        add     edi,[first_write_length]
        cmp     edi,[first_write]
        jbe     move_second_part
        mov     edi,[first_write]
        add     edi,[first_write_length]
    move_second_part:
        push    edi
        mov     ecx,[second_write_length]
        lea     eax,[edi+ecx]
        cmp     eax,[tagged_blocks]
        ja      out_of_memory
        call    move_block
        mov     edi,[second_write]
        mov     esi,[first_write]
        mov     ecx,[first_write_length]
        call    move_block
        pop     esi
        mov     ecx,[second_write_length]
        call    move_block
        mov     ecx,edi
        sub     ecx,[ebx+FASM_STATE.output_data]
        mov     [ebx+FASM_STATE.output_length],ecx
        retn

  display_block:
        mov     eax,[display_pipe]
        or      eax,eax
        jz      display_ok
        invoke  WriteFile,eax,esi,ecx,tmp,NULL
    display_ok:
        retn

  make_timestamp:
        invoke  GetSystemTime,systime
        movzx   ecx,[systime.wYear]
        mov     eax,ecx
        sub     eax,1970
        mov     ebx,365
        mul     ebx
        mov     ebp,eax
        mov     eax,ecx
        sub     eax,1969
        shr     eax,2
        add     ebp,eax
        mov     eax,ecx
        sub     eax,1901
        mov     ebx,100
        div     ebx
        sub     ebp,eax
        mov     eax,ecx
        xor     edx,edx
        sub     eax,1601
        mov     ebx,400
        div     ebx
        add     ebp,eax
        movzx   ecx,[systime.wMonth]
        mov     eax,ecx
        dec     eax
        mov     ebx,30
        mul     ebx
        add     ebp,eax
        cmp     ecx,8
        jbe     months_correction
        mov     eax,ecx
        sub     eax,7
        shr     eax,1
        add     ebp,eax
        mov     ecx,8
      months_correction:
        mov     eax,ecx
        shr     eax,1
        add     ebp,eax
        cmp     ecx,2
        jbe     day_correction_ok
        sub     ebp,2
        movzx   ecx,word [systime.wYear]
        test    ecx,11b
        jnz     day_correction_ok
        xor     edx,edx
        mov     eax,ecx
        mov     ebx,100
        div     ebx
        or      edx,edx
        jnz     day_correction
        mov     eax,ecx
        mov     ebx,400
        div     ebx
        or      edx,edx
        jnz     day_correction_ok
      day_correction:
        inc     ebp
      day_correction_ok:
        movzx   eax,[systime.wDay]
        dec     eax
        add     eax,ebp
        mov     ebx,24
        mul     ebx
        movzx   ecx,[systime.wHour]
        add     eax,ecx
        mov     ebx,60
        mul     ebx
        movzx   ecx,[systime.wMinute]
        add     eax,ecx
        mov     ebx,60
        mul     ebx
        movzx   ecx,[systime.wSecond]
        add     eax,ecx
        retn

dump_symbols:
        retn

include 'errors.inc'
include '..\version.inc'

include '..\preproce.inc'
include '..\parser.inc'
include '..\exprpars.inc'
include '..\exprcalc.inc'
include '..\assemble.inc'
include '..\formats.inc'
fatal_error equ assembler_error

include '..\armv8.inc'
include '..\armtable.inc'


null_byte db 0

section '.idata' import data readable writeable

  library kernel32,'KERNEL32.DLL'

  include 'os specific/windows/api/x86/kernel32.inc'

section '.edata' export data readable

  export 'FASM.DLL',\
         fasm_GetVersion,'fasm_GetVersion',\
         fasm_Assemble,'fasm_Assemble',\
         fasm_AssembleFile,'fasm_AssembleFile'

section '.reloc' fixups data readable discardable

section '.rsrc' resource data readable

  directory RT_VERSION,versions

  resource versions,\
           1,LANG_NEUTRAL,version

  versioninfo version,VOS__WINDOWS32,VFT_APP,VFT2_UNKNOWN,LANG_ENGLISH+SUBLANG_DEFAULT,0,\
              'FileDescription','flat assembler',\
              'LegalCopyright',<'Copyright ',0A9h,' 2001-2019 Tomasz Grysztar, 2005-2019 Revolution'>,\
              'FileVersion',ARM_VERSION_STRING,\
              'ProductVersion',ARM_VERSION_STRING,\
              'OriginalFilename','FASMARM.DLL'
    

I don`t shure about correct copyright and versioning. But dll created workable.
only line " include 'os specific/windows/api/x86/kernel32.inc'" should be replaced with "include 'api\kernel32.inc'"
Post 22 Apr 2019, 23:34
View user's profile Send private message Send e-mail Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 798
Location: Russian Federation, Sochi
ProMiNick 22 Apr 2019, 23:59
And last more: assumptions maked by Tomasz for porting fasm core code from x86 to x64 couldb`t be applied to fasmarm code. so no x64 versions (atleast patch macro should be realized differently)
Post 22 Apr 2019, 23:59
View user's profile Send private message Send e-mail Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.