flat assembler
Message board for the users of flat assembler.

Index > Compiler Internals > Changing the "target"-extension with a directive

Author
Thread Post new topic Reply to topic
MCD



Joined: 21 Aug 2004
Posts: 602
Location: Germany
MCD 16 Dec 2004, 18:29
I managed to implement a "target" directive into Fasm which allows to
overwrite the default file extension for the output file. If you need other
extensions than those guessed by Fasm, then always renaming those files is
enoying.
The syntax is as simple as follows:

Code:
target    Some_string_specifying_an_output_extension
    


The "target" directive can only be specified once and only before the actual
code starts (like the "format" directive).
The extension must have a length between 0 and 4 characters. An empty string
means no extension at all. If no target directive is specified, then the
default, guessed extension (old behaviour of Fasm, backward compatible Wink)
is used. But still the output file can always be overwritten at the
command prompt with

fasm input_file.extension [output_file.extension]

Lets assume you have a file called "MYFILE.ASM", then this:
Code:
target "JPEG";If someone wants to declare JPEG data files with Fasm Wink
    

would give an output file like "MYFILE.JPEG",

and this
Code:
target       ""
    

would simply give "MYFILE".

_________________
MCD - the inevitable return of the Mad Computer Doggy

-||__/
.|+-~
.|| ||
Post 16 Dec 2004, 18:29
View user's profile Send private message Reply with quote
MCD



Joined: 21 Aug 2004
Posts: 602
Location: Germany
MCD 16 Dec 2004, 18:33
The limit of 4 characters is due to the use of a "dd" as the output extension string, but this could easily be changed if needed.

This new directive only needs some dozens of new instruction (see next),
so implementing won't bload Fasm to much. The problem is that I don't know if anyone else needs this feature, post me.


Last edited by MCD on 16 Dec 2004, 18:40; edited 1 time in total
Post 16 Dec 2004, 18:33
View user's profile Send private message Reply with quote
MCD



Joined: 21 Aug 2004
Posts: 602
Location: Germany
MCD 16 Dec 2004, 18:34
AND HERE IS HOW TO IMPLEMENT IT

Several small to medium changes must be done, and unfortunately in different
files, namely "FASM.ASM/INC" (the main fasm file), "FORMATS.INC", "X86.INC"
and "ASSEMBLE.INC". I prefer specifying old/new parts instead of line numbers
since line numbers can change easily.
Let's start with the files with the least code to change.

Changes in "FASM.ASM/INC":
--------------------------

Somewhere at the end, with many undefined data directives.
Old:
Code:
output_file dd ?
    


New:
Code:
output_file dd ?
output_extension dd ?;<-- here
    


Changes in "ASSEMBLE.INC":
--------------------------

Right at the very beginning after the first label.
Old:
Code:
assembler:
;       ...
    


New:
Code:
assembler:
;       ...     should be ~12 lines
    mov     byte [output_extension],al;<-- here
    


Changes in "X86.INC":
---------------------

Somewhere at the end where all the instructions are listed.
Old:
Code:
instructions_6:
;       ...     should be ~220 to 250 lines
 db 'sqrtss',51h
 dw sse_ss_instruction-assembler
    


New:
Code:
instructions_6:
;       ...     should be ~220 to 250 lines
 db 'sqrtss',51h
 dw sse_ss_instruction-assembler
 db 'target',0               ;\__ here
 dw target_directive-assembler;/
    


Changes in "FORMATS.INC":
-------------------------

Right at the very beginning after the first label.
The changes in "FORMATS.INC" are the biggest.

Old:
Code:
formatter:
      cmp     [output_file],0
     jne     output_path_ok
      push    edi
 mov     esi,[input_file]
    mov     edi,[free_additional_memory]
      copy_output_path:
 lods    byte [esi]
  cmp     edi,[structures_buffer]
     jae     out_of_memory
       stos    byte [edi]
  or      al,al
       jnz     copy_output_path
    dec     edi
 mov     eax,edi
      find_extension:
        dec     eax
 cmp     eax,[free_additional_memory]
        jb      extension_found
     cmp     byte [eax],'\'
   je      extension_found
     cmp     byte [eax],'/'
    je      extension_found
     cmp     byte [eax],'.'
    jne     find_extension
      mov     edi,eax
      extension_found:
       lea     eax,[edi+9]
 cmp     eax,[structures_buffer]
     jae     out_of_memory
       cmp     [output_format],2
   je      exe_extension
       jb      bin_extension
       cmp     [output_format],4
   je      obj_extension
       cmp     [output_format],5
   je      o_extension
 cmp     [output_format],3
   jne     no_extension
        cmp     [subsystem],1
       je      sys_extension
       bt      [format_flags],8
    jnc     exe_extension
       mov     eax,'.dll'
        jmp     make_extension
      sys_extension:
  mov     eax,'.sys'
        jmp     make_extension
      bin_extension:
  mov     eax,'.bin'
        bt      [format_flags],0
    jnc     make_extension
      mov     eax,'.com'
        jmp     make_extension
      obj_extension:
  mov     eax,'.obj'
        jmp     make_extension
      o_extension:
    mov     eax,'.o'
  bt      [format_flags],0
    jnc     make_extension
      no_extension:
   xor     eax,eax
     jmp     make_extension
      exe_extension:
  mov     eax,'.exe'
      make_extension:
   xchg    eax,[edi]
   scas    dword [edi]
 mov     byte [edi],0
        scas    byte [edi]
  mov     esi,edi
     stos    dword [edi]
 sub     edi,9
       xor     eax,eax
     mov     ebx,characters
      adapt_case:
     mov     al,[esi]
    or      al,al
       jz      adapt_next
  xlat    byte [ebx]
  cmp     al,[esi]
    je      adapt_ok
    sub     byte [edi],20h
      adapt_ok:
       inc     esi
      adapt_next:
        inc     edi
 cmp     byte [edi],0
        jne     adapt_case
  mov     esi,edi
     lea     ecx,[esi+1]
 sub     ecx,[free_additional_memory]
        mov     edi,[structures_buffer]
     dec     edi
 std
 rep     movs byte [edi],[esi]
       cld
 inc     edi
 mov     [structures_buffer],edi
     mov     [output_file],edi
   pop     edi
      output_path_ok:
    cmp     [output_format],4
   je      coff_formatter
      cmp     [output_format],5
   jne     common_formatter
    bt      [format_flags],0
    jnc     elf_formatter
      common_formatter:
        mov     eax,edi
     sub     eax,[code_start]
    mov     [real_code_size],eax
        cmp     edi,[undefined_data_end]
    jne     calculate_code_size
 mov     edi,[undefined_data_start]
      calculate_code_size:
        sub     edi,[code_start]
    mov     [code_size],edi
     mov     [written_size],0
    mov     edx,[output_file]
   call    create
      jc      write_failed
        cmp     [output_format],3
   jne     stub_written
        mov     edx,[code_start]
    mov     ecx,[stub_size]
     sub     edx,ecx
     add     [written_size],ecx
  call    write
      stub_written:
    cmp     [output_format],2
   jne     write_output
        call    write_mz_header
      write_output:
  call    write_code
      output_written:
     call    close
       ret
      write_code:
        mov     eax,[written_size]
  mov     [headers_size],eax
  mov     edx,[code_start]
    mov     ecx,[code_size]
     add     [written_size],ecx
  call    write
       jc      write_failed
        ret
    


New:
Code:
formatter:
    cmp     [output_file],0
     jne     output_path_ok
      push    edi
 mov     esi,[input_file]
    mov     edi,[free_additional_memory]
    copy_output_path:
   lods    byte [esi]
  cmp     edi,[structures_buffer]
     jae     out_of_memory
       stos    byte [edi]
  or      al,al
       jnz     copy_output_path
    dec     edi
 mov     edx,edi
    find_extension:
  dec     edx
 cmp     edx,[free_additional_memory]
        jb      extension_found
     mov     al,[edx]
    cmp     al,'\'
   je      extension_found
     cmp     al,'/'
    je      extension_found
     cmp     al,'.'
    jne     find_extension
      mov     edi,edx
    extension_found:
 lea     eax,[edi+10]
        cmp     eax,[structures_buffer]
     jae     out_of_memory
       mov     al,'.'
    stos    byte [edi]
  mov     eax,[output_extension]
      cmp     al,0Ah
      je      no_extension
        or      al,al
       jnz     make_extension
      cmp     [output_format],2
   je      exe_extension
       jb      bin_extension
       cmp     [output_format],4
   je      obj_extension
       cmp     [output_format],5
   je      o_extension
 cmp     [output_format],3
   jne     no_extension
        cmp     [subsystem],1
       je      sys_extension
       bt      [format_flags],8
    jnc     exe_extension
       mov     eax,'dll'
 jmp     make_extension
    sys_extension:
    mov     eax,'sys'
 jmp     make_extension
    bin_extension:
    mov     eax,'bin'
 bt      [format_flags],0
    jnc     make_extension
      mov     eax,'com'
 jmp     make_extension
    obj_extension:
    mov     eax,'obj'
 jmp     make_extension
    o_extension:
      mov     ax,'o'
    bt      [format_flags],0
    jnc     make_extension
    no_extension:
     dec     edi
 xor     al,al
       stos    byte [edi]
  jmp     make_extension
    exe_extension:
    mov     eax,'exe'
    make_extension:
      mov     edx,[edi]
   stos    dword [edi]
 mov     ax,'.' shl 8
      stos    word [edi]
  mov     [edi],edx
   lea     esi,[edi-6]
 mov     ebx,characters
    adapt_case:
       mov     al,[edi]
    or      al,al
       jz      adapt_next
  xlat    byte [ebx]
  cmp     al,[edi]
    je      adapt_ok
    and     byte [esi],0DFh
    adapt_ok:
        inc     edi
    adapt_next:
  inc     esi
 cmp     byte [esi],0
        jne     adapt_case
  lea     ecx,[esi+1]
 sub     ecx,[free_additional_memory]
        mov     edi,[structures_buffer]
     dec     edi
 std
 rep     movs byte [edi],[esi]
       cld
 inc     edi
 mov     [structures_buffer],edi
     mov     [output_file],edi
   pop     edi
    output_path_ok:
      cmp     [output_format],4
   je      coff_formatter
      cmp     [output_format],5
   jne     common_formatter
    bt      [format_flags],0
    jnc     elf_formatter
    common_formatter:
  mov     eax,edi
     sub     eax,[code_start]
    mov     [real_code_size],eax
        cmp     edi,[undefined_data_end]
    jne     calculate_code_size
 mov     edi,[undefined_data_start]
    calculate_code_size:
  sub     edi,[code_start]
    mov     [code_size],edi
     xor     eax,eax
     mov     [written_size],eax
  mov     edx,[output_file]
   call    create
      jc      write_failed
        cmp     [output_format],3
   jne     stub_written
        mov     edx,[code_start]
    mov     ecx,[stub_size]
     sub     edx,ecx
     add     [written_size],ecx
  call    write
    stub_written:
      cmp     [output_format],2
   jne     write_output
        call    write_mz_header
    write_output:
    call    write_code
    output_written:
       call    close
       ret
    write_code:
  mov     eax,[written_size]
  mov     [headers_size],eax
  mov     edx,[code_start]
    mov     ecx,[code_size]
     add     [written_size],ecx
  call    write
       jc      write_failed
        ret
target_directive:
        cmp     edi,[code_start]
    jne     unexpected_instruction
      cmp     [virtual_data],0
    jne     unexpected_instruction
      cmp     byte [output_extension],0
   jne     unexpected_instruction
      lods    word [esi]
  cmp     ax,28h
      jne     invalid_argument
    lods    dword [esi]
 cmp     eax,4
       ja      name_too_long
       mov     edx,[esi]
   or      dl,dl
       jnz     output_extension_ok
 mov     dl,0Ah
    output_extension_ok:
      mov     [output_extension],edx
      add     esi,eax
     inc     esi
 jmp     instruction_assembled
    


Please keep in mind that I coded this on my own with no "guide to fasm's internals at all, I took 2 days just to analyze the formatter/assembler enough to start a try. Shocked

_________________
MCD - the inevitable return of the Mad Computer Doggy

-||__/
.|+-~
.|| ||
Post 16 Dec 2004, 18:34
View user's profile Send private message Reply with quote
MCD



Joined: 21 Aug 2004
Posts: 602
Location: Germany
MCD 16 Dec 2004, 18:41
also, if implemented, this directive should be mentioned in the documentation
Post 16 Dec 2004, 18:41
View user's profile Send private message Reply with quote
MCD



Joined: 21 Aug 2004
Posts: 602
Location: Germany
MCD 16 Dec 2004, 18:44
okay, here is an example that uses the new "target" directive. It is my old
Mandelbrot-set TGA-image code.
Code:
; WARNING! This code compiles extremely SLOW!

; DON'T _RUN_ this file, just COMPILE it and view it with any
; image program that supports 8-bit paletted TGA-images (many does).

; This is an example that shows the power and flexibility of FASM's syntax.
; It will compile(!) to a mandelbrot-set image using data defining
; directives and thus it doesn't need to be run.

target    "TGA"; no more renaming :p

; Some basic image properties. Feel free to modify
Width     equ 128
Height       equ 128
IterLim equ 255; = MaxIter - 1
Prec       equ 29; don't set above 29 nor to low, else image may be scrambled

sar  equ /1 shl; This example really needs a sar operator lOl

; TGA-header: 8-bit paletted image
dw 256,1
db 0,0,1,24
dw 0,0,Width,Height
db 8,8

; palette: 256*3bytes (RGB)
repeat 256
 Tmp = %*%
 Tmp = (Tmp*Tmp*Tmp*% - 1) shr 48
 db (Tmp+55h) and 0FFh
 db (Tmp+0AAh) and 0FFh
 db Tmp
end repeat

; actual image (Mandelbrot fractal)
StepR = (5 shl (Prec-1) +Width       shr 1) / Width; = 2.5/Width
StepI = (5 shl (Prec-1) +Height shr 1) / Height; = 3/Height

PosI = -5 shl (Prec-2); = -1.25
repeat Height
 PosR = -2 shl Prec; = -2
 repeat Width
  R = PosR
  I = PosI
  RR = (PosR*PosR) shr Prec
  II = (PosI*PosI) shr Prec

  Color = IterLim; Color is also the current iteration number
  repeat IterLim
   if (RR + II) < 4 shl Prec
    Tmp = (RR - II) + PosR
    I = (R*I) sar (Prec-1) + PosI
    R = Tmp
    RR = (Tmp*Tmp) shr Prec
    II = (I*I) shr Prec
    Color = Color - 1; discounting Color
   end if
  end repeat
  db Color

  PosR = PosR + StepR
 end repeat
 PosI = PosI + StepI
end repeat
    

_________________
MCD - the inevitable return of the Mad Computer Doggy

-||__/
.|+-~
.|| ||
Post 16 Dec 2004, 18:44
View user's profile Send private message Reply with quote
pelaillo
Missing in inaction


Joined: 19 Jun 2003
Posts: 878
Location: Colombia
pelaillo 16 Dec 2004, 21:14
I like it that way. Very useful indeed. Better if we can decide filename also with target directive.

Code:
target extension,[filename]    


We've arleady discussed similar things with Privalov here: http://board.flatassembler.net/topic.php?t=1820
Post 16 Dec 2004, 21:14
View user's profile Send private message Yahoo Messenger Reply with quote
MCD



Joined: 21 Aug 2004
Posts: 602
Location: Germany
MCD 16 Dec 2004, 21:40
I remember this discussion. But at this time, such a directive was considered "a bit ambiguous". But now, with my Mandelbrot-set TGA and Beat/Noise-WAV examples, this directive may become really handy.

Especially when defining data files with Fasm Wink

Okay, forget about these data files, because this is not what Fasm was made for.

But what if you code an exotic binary, say, a DOS/Windows devic driver, renaming those output file extensions manually to ".SYS" or ".VXD" _IS_ ennoying. What do you think?

Or you could override the target extension to ".SS" for DOS Navigator screen savers. ".SCR" for Windows screen savers.
Post 16 Dec 2004, 21:40
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 16 Dec 2004, 23:13
Quote:
But what if you code an exotic binary, say, a DOS/Windows devic driver, renaming those output file extensions manually to ".SYS" or ".VXD" _IS_ ennoying. What do you think?

Sorry, but what do you think second fasm's command line argument is for?

Contents of destination file should be controlled by source and attributes (name, flags, destination path etc) by compiler's arguments.

But as FASM's source module it is okay, for people who like it.
Post 16 Dec 2004, 23:13
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
MCD



Joined: 21 Aug 2004
Posts: 602
Location: Germany
MCD 16 Dec 2004, 23:20
I mean, when assembling files under the FasmW IDE, you cannot specify an output extension, unless someone adds an output extension edit box. (could be compiler setup > target). Perhaps it would be nicer to add such a target edit box rather then adding a formatter directive direcly into Fasm.

I had done this before I added the "target" directive, but somehow I felt not lucky with it. Don't know.
Post 16 Dec 2004, 23:20
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 17 Dec 2004, 09:25
i think that would be better.

Tomasz: Could you add that to FASMW?
Post 17 Dec 2004, 09:25
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
pelaillo
Missing in inaction


Joined: 19 Jun 2003
Posts: 878
Location: Colombia
pelaillo 20 Dec 2004, 13:31
vid wrote:
Sorry, but what do you think second fasm's command line argument is for?


Please remember that one of the fasm's goals is to have souces self-determined or in other words, avoiding command line settings that could affect the final result.

All the recipe for the file creation is inside the source file itself. The princilpe is the same here, and as usual, it is optional and there is a default.
Post 20 Dec 2004, 13:31
View user's profile Send private message Yahoo Messenger Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8357
Location: Kraków, Poland
Tomasz Grysztar 20 Dec 2004, 15:47
Quote:
Please remember that one of the fasm's goals is to have souces self-determined or in other words, avoiding command line settings that could affect the final result.

But that "final result" was in my interpretation only the output code itself, that is the contents of the file, not the file attributes.

I agree that FASMW should have the output name/extension setting, to give it the same functionality as the console versions have. I will add it soon.
Post 20 Dec 2004, 15:47
View user's profile Send private message Visit poster's website Reply with quote
MCD



Joined: 21 Aug 2004
Posts: 602
Location: Germany
MCD 21 Dec 2004, 16:38
thanks
Post 21 Dec 2004, 16:38
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 22 Dec 2004, 19:25
great
Post 22 Dec 2004, 19:25
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
halyavin



Joined: 21 Aug 2004
Posts: 42
halyavin 25 Jan 2005, 10:29
Privalov
Will you also add directive "target"?
Post 25 Jan 2005, 10:29
View user's profile Send private message Visit poster's website Reply with quote
MCD



Joined: 21 Aug 2004
Posts: 602
Location: Germany
MCD 02 Feb 2005, 14:11
Quote:
Privalov
Will you also add directive "target"?
I think not, but who knows?
Post 02 Feb 2005, 14:11
View user's profile Send private message 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.