flat assembler
Message board for the users of flat assembler.

Index > Main > [solved] Assembling of a relatively large program fails

Author
Thread Post new topic Reply to topic
DSblizzard



Joined: 23 Oct 2019
Posts: 15
Location: Ryazan, Russia
DSblizzard
I'm trying to assemble program with 300 kloc and fasm fails with error message "error: out of memory.". Is memory consumption 1 GB for this program normal?
Post 07 Dec 2019, 20:39
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17064
Location: In your JS exploiting you and your system
revolution
Which version of fasm are you using?

For the command line version you can use the -m switch.
For the GUI version you can set the memory through the menus.

Regarding the memory usage it depends upon many factors, not only the line count. If you use a lot of macros and preprocessor repeated blocks then memory usage will be higher. 1GB is not unknown.
Post 07 Dec 2019, 21:17
View user's profile Send private message Visit poster's website Reply with quote
moveax41h



Joined: 18 Feb 2018
Posts: 59
moveax41h
Always remember, that's like 1/4th of what 1 Electron application takes in RAM to run...
Post 08 Dec 2019, 01:22
View user's profile Send private message Reply with quote
DSblizzard



Joined: 23 Oct 2019
Posts: 15
Location: Ryazan, Russia
DSblizzard
Version 1.73.16. I almost don't use macros. I can understand if program increases several times in size, but 150 times is a total mystery. It's just generated source of toy compiler. How are really large programs supposed to be assembled? (3GB with -m will not be enough).
When I try to invoke fasm with
Quote:
fasm.exe -m 2000000 1.asm test\1.exe

fasm output is:
Quote:
flat assembler version 1.73.16 (1000000 kilobytes memory)
error: out of memory.


Last edited by DSblizzard on 08 Dec 2019, 07:36; edited 1 time in total
Post 08 Dec 2019, 07:23
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17064
Location: In your JS exploiting you and your system
revolution
If you have large blocks of uninitialised data then that is also held in memory.
Code:
rb 1 shl 30 ; 1 GB memory usage
db 0    
Post 08 Dec 2019, 07:33
View user's profile Send private message Visit poster's website Reply with quote
DSblizzard



Joined: 23 Oct 2019
Posts: 15
Location: Ryazan, Russia
DSblizzard
No, only 4 MB of static data. I edited previous post.
Post 08 Dec 2019, 07:38
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17064
Location: In your JS exploiting you and your system
revolution
The Windows version can't allocate 2GB because of the system libraries loaded in the middle of the address space. Try with 1.9GB, or 1.8GB, or similar, to get the maximum available allocation.
Post 08 Dec 2019, 07:41
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: 17064
Location: In your JS exploiting you and your system
revolution
If you still have trouble you can maximise the allocation strategy with some modifications as shown in this topic:

https://board.flatassembler.net/topic.php?t=17667
Post 08 Dec 2019, 08:03
View user's profile Send private message Visit poster's website Reply with quote
DSblizzard



Joined: 23 Oct 2019
Posts: 15
Location: Ryazan, Russia
DSblizzard
It seems that fasm has great trouble. Such a huge increase in size is unforgivable.
Post 08 Dec 2019, 08:32
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17064
Location: In your JS exploiting you and your system
revolution
DSblizzard wrote:
It seems that fasm has great trouble. Such a huge increase in size is unforgivable.
We don't know what you are doing, so we are left to guess at possible reasons and solutions. But if you post a representative snippet of your code perhaps we can spot something unusual or problematic.
Post 08 Dec 2019, 08:35
View user's profile Send private message Visit poster's website Reply with quote
DSblizzard



Joined: 23 Oct 2019
Posts: 15
Location: Ryazan, Russia
DSblizzard
Code:
; compile_assign
push r12

; compile_fn get_field_by_key
push r12
push r13
; compile args start
mov r11, -48
add r11, [def_stack_ptr]
mov rax, [r11 + VarValOffset] ; & joint
mov r11, [transient_ptr]
mov qword [r11], VarT
mov [r11 + VarValOffset], rax
add [transient_ptr], VarHeaderSize
mov r11, -32
add r11, [def_stack_ptr]
mov rax, [r11 + VarValOffset] ; & joint
mov r11, [transient_ptr]
mov qword [r11], VarT
mov [r11 + VarValOffset], rax
add [transient_ptr], VarHeaderSize
; compile args end
mov r12, [transient_ptr]
add [transient_ptr], 48 ; VarsOffset + VarsSize
mov r13, [def_stack_ptr]
mov [r13 + NextDefPtrOffset], r12
mov [r12 + PrevDefPtrOffset], r13
mov qword [def_stack_ptr], r12
; call
cmp qword [is_debug], 0
je raw_call_951
cmp qword [is_print_arg], 1
je raw_call_951
cmp qword [is_collect_garbage], 1
je raw_call_951
push_regs
mov r12, [debug_call_level]
mov byte [spaces + r12], EOS
cinvoke printf, <"%sstart compiled_get_field_by_key", 13, 10>, spaces
mov byte [spaces + r12], 32 ; space
add r12, 2
mov [debug_call_level], r12
pop_regs
call compiled_get_field_by_key
push_regs
mov r12, [debug_call_level]
sub r12, 2
mov byte [spaces + r12], EOS
cinvoke printf, <"%send   compiled_get_field_by_key", 13, 10>, spaces
mov byte [spaces + r12], 32 ; space
mov [debug_call_level], r12
pop_regs_label_951:
pop_regs
jmp end_emit_call_951
raw_call_951:
call compiled_get_field_by_key
end_emit_call_951:
; end of call
mov qword [def_stack_ptr], r13
mov qword [r13 + NextDefPtrOffset], 0
mov qword [transient_ptr], r12
pop r13
pop r12
; end of compile_fn get_field_by_key
; call
cmp qword [is_debug], 0
je raw_call_952
cmp qword [is_print_arg], 1
je raw_call_952
cmp qword [is_collect_garbage], 1
je raw_call_952
push_regs
mov r12, [debug_call_level]
mov byte [spaces + r12], EOS
cinvoke printf, <"%sstart check_and_change_res_type_to_ValPtr", 13, 10>, spaces
mov byte [spaces + r12], 32 ; space
add r12, 2
mov [debug_call_level], r12
pop_regs
call check_and_change_res_type_to_ValPtr
push_regs
mov r12, [debug_call_level]
sub r12, 2
mov byte [spaces + r12], EOS
cinvoke printf, <"%send   check_and_change_res_type_to_ValPtr", 13, 10>, spaces
mov byte [spaces + r12], 32 ; space
mov [debug_call_level], r12
pop_regs_label_952:
pop_regs
jmp end_emit_call_952
raw_call_952:
call check_and_change_res_type_to_ValPtr
end_emit_call_952:
; end of call
mov r11, 2
imul r11, VarHeaderSize
sub [transient_ptr], r11
mov r11, [transient_ptr]
mov qword [r11], VarT
mov [r11 + VarValOffset], rax
add [transient_ptr], VarHeaderSize
mov r12, rax ; & val
lea r11, [VarsOffset + 0]
add r11, [def_stack_ptr]
mov rax, [r11 + VarValOffset] ; & joint
mov [rax + JointValOffset], r12
mov [data_sub], rax
mov rax, r12
pop r12
; end of compile_assign
    


Code:
; compile_fn emit
push r12
push r13
; compile args start

; compile_str_box
mov rdi, s_4830
mov qword rsi, 12
; call
cmp qword [is_debug], 0
je raw_call_4831
cmp qword [is_print_arg], 1
je raw_call_4831
cmp qword [is_collect_garbage], 1
je raw_call_4831
push_regs
mov r12, [debug_call_level]
mov byte [spaces + r12], EOS
cinvoke printf, <"%sstart str_to_malloc", 13, 10>, spaces
mov byte [spaces + r12], 32 ; space
add r12, 2
mov [debug_call_level], r12
pop_regs
call str_to_malloc
push_regs
mov r12, [debug_call_level]
sub r12, 2
mov byte [spaces + r12], EOS
cinvoke printf, <"%send   str_to_malloc", 13, 10>, spaces
mov byte [spaces + r12], 32 ; space
mov [debug_call_level], r12
pop_regs_label_4831:
pop_regs
jmp end_emit_call_4831
raw_call_4831:
call str_to_malloc
end_emit_call_4831:
; end of call
; end of compile_str_box
mov r11, [transient_ptr]
mov qword [r11], VarT
mov [r11 + VarValOffset], rax
add [transient_ptr], VarHeaderSize
lea r11, [VarsOffset + 0]
add r11, [def_stack_ptr]
mov rax, [r11 + VarValOffset] ; & joint
mov rax, [rax + JointValOffset]
mov r11, [transient_ptr]
mov qword [r11], VarT
mov [r11 + VarValOffset], rax
add [transient_ptr], VarHeaderSize
mov r10, 2
; call
cmp qword [is_debug], 0
je raw_call_4833
cmp qword [is_print_arg], 1
je raw_call_4833
cmp qword [is_collect_garbage], 1
je raw_call_4833
push_regs
mov r12, [debug_call_level]
mov byte [spaces + r12], EOS
cinvoke printf, <"%sstart fn_add", 13, 10>, spaces
mov byte [spaces + r12], 32 ; space
add r12, 2
mov [debug_call_level], r12
pop_regs
call fn_add
push_regs
mov r12, [debug_call_level]
sub r12, 2
mov byte [spaces + r12], EOS
cinvoke printf, <"%send   fn_add", 13, 10>, spaces
mov byte [spaces + r12], 32 ; space
mov [debug_call_level], r12
pop_regs_label_4833:
pop_regs
jmp end_emit_call_4833
raw_call_4833:
call fn_add
end_emit_call_4833:
; end of call
mov r11, 2
imul r11, VarHeaderSize
sub [transient_ptr], r11
mov [gc_root], rax
mov rdi, rax
; call
cmp qword [is_debug], 0
je raw_call_4834
cmp qword [is_print_arg], 1
je raw_call_4834
cmp qword [is_collect_garbage], 1
je raw_call_4834
push_regs
mov r12, [debug_call_level]
mov byte [spaces + r12], EOS
cinvoke printf, <"%sstart new_joint_header", 13, 10>, spaces
mov byte [spaces + r12], 32 ; space
add r12, 2
mov [debug_call_level], r12
pop_regs
call new_joint_header
push_regs
mov r12, [debug_call_level]
sub r12, 2
mov byte [spaces + r12], EOS
cinvoke printf, <"%send   new_joint_header", 13, 10>, spaces
mov byte [spaces + r12], 32 ; space
mov [debug_call_level], r12
pop_regs_label_4834:
pop_regs
jmp end_emit_call_4834
raw_call_4834:
call new_joint_header
end_emit_call_4834:
; end of call
mov [rax + JointValOffset], rdi
mov r11, [transient_ptr]
mov qword [r11], VarT
mov [r11 + VarValOffset], rax
add [transient_ptr], VarHeaderSize
; compile args end
mov r12, [transient_ptr]
add [transient_ptr], 48 ; VarsOffset + VarsSize
mov r13, [def_stack_ptr]
mov [r13 + NextDefPtrOffset], r12
mov [r12 + PrevDefPtrOffset], r13
mov qword [def_stack_ptr], r12
; call
cmp qword [is_debug], 0
je raw_call_4835
cmp qword [is_print_arg], 1
je raw_call_4835
cmp qword [is_collect_garbage], 1
je raw_call_4835
push_regs
mov r12, [debug_call_level]
mov byte [spaces + r12], EOS
cinvoke printf, <"%sstart compiled_emit", 13, 10>, spaces
mov byte [spaces + r12], 32 ; space
add r12, 2
mov [debug_call_level], r12
pop_regs
call compiled_emit
push_regs
mov r12, [debug_call_level]
sub r12, 2
mov byte [spaces + r12], EOS
cinvoke printf, <"%send   compiled_emit", 13, 10>, spaces
mov byte [spaces + r12], 32 ; space
mov [debug_call_level], r12
pop_regs_label_4835:
pop_regs
jmp end_emit_call_4835
raw_call_4835:
call compiled_emit
end_emit_call_4835:
; end of call
mov qword [def_stack_ptr], r13
mov qword [r13 + NextDefPtrOffset], 0
mov qword [transient_ptr], r12
pop r13
pop r12
; end of compile_fn emit
    
Post 08 Dec 2019, 08:52
View user's profile Send private message Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7618
Location: Kraków, Poland
Tomasz Grysztar
It's the macro calls like this one:
Code:
cinvoke printf,<'%sstart str_to_malloc',13,10>,spaces    
The fastcall is a long and complex macro, if you use PREPSRC tool to extract the preprocessed source from the .FAS file, you can see that this single line ends up being expanded into around 1200 lines of preprocessed text:
Code:
;cinvoke printf,<'%sstart str_to_malloc',13,10>,spaces


;ccall[printf],<'%sstart str_to_malloc',13,10>,spaces


vararg@fastcall=1
;fastcall[printf],<'%sstart str_to_malloc',13,10>,spaces


; list?Sf counter?Sg flags?Sh outer_frame?Si nested_frame?Sj ..close_nest?Sk
;match=current@frame,current@frame{
; frame
; define outer_frame?Si}
;frame
; size?Sl current?Sm
if size?Sl
sub rsp,size?Sl
end if
current?Sm=0
;current@frame equ current?Sm
;size@frame equ size?Sl
;define outer_frame?Si
;define counter?Sg
;define list?Sf
flags?Sh=0

; param?Sn nested?So isfloat?Sp ..next?Sq
;match any,{list?Sf equ list?Sf,}
;counter?Sg equ+1
;define param?Sn '%sstart str_to_malloc',13,10
;define nested?So
isfloat?Sp=0
;match=invoke statement,'%sstart str_to_malloc',13,10{
; nested?So equ param?Sn
; define param?Sn}
;match=fastcall statement,'%sstart str_to_malloc',13,10{
; nested?So equ param?Sn
; define param?Sn}
;match=float=invoke statement,'%sstart str_to_malloc',13,10{
; define nested?So invoke statement
; define param?Sn
; isfloat?Sp=1}
;match=float=fastcall statement,'%sstart str_to_malloc',13,10{
; define nested?So fastcall statement
; define param?Sn
; isfloat?Sp=1}
;match statement,{
; match=nested_frame?Sj,nested_frame?Sj \{
; frame
; define nested_frame?Sj \}
; allow_nesting
; statement
; purge invoke_fastcall
; if counter?Sg>4
; if isfloat?Sp
; movq[rsp+size@frame+(counter?Sg-1)*8],xmm0
; else
; mov[rsp+size@frame+(counter?Sg-1)*8],rax
; end if
; else
; flags?Sh=flags?Sh or 1 shl(counter?Sg-1)
; if isfloat?Sp
; flags?Sh=flags?Sh or 1 shl(4+counter?Sg-1)
; end if
; if ..close_nest?Sk>..next?Sq
; if float
; movq[rsp+size@frame+(counter?Sg-1)*8],xmm0
; else
; mov[rsp+size@frame+(counter?Sg-1)*8],rax
; end if
; else
; flags?Sh=flags?Sh or 1 shl(8+counter?Sg-1)
; end if
; end if
; ..next?Sq:}
;list?Sf equ<'%sstart str_to_malloc',13,10>

; param?Sr nested?Ss isfloat?St ..next?Su
;match any,+1{list?Sf equ list?Sf,}
;list?Sf equ<'%sstart str_to_malloc',13,10>,
;counter?Sg equ+1+1
;define param?Sr spaces
;define nested?Ss
isfloat?St=0
;match=invoke statement,spaces{
; nested?Ss equ param?Sr
; define param?Sr}
;match=fastcall statement,spaces{
; nested?Ss equ param?Sr
; define param?Sr}
;match=float=invoke statement,spaces{
; define nested?Ss invoke statement
; define param?Sr
; isfloat?St=1}
;match=float=fastcall statement,spaces{
; define nested?Ss fastcall statement
; define param?Sr
; isfloat?St=1}
;match statement,{
; match=nested_frame?Sj,nested_frame?Sj \{
; frame
; define nested_frame?Sj \}
; allow_nesting
; statement
; purge invoke_fastcall
; if counter?Sg>4
; if isfloat?St
; movq[rsp+size@frame+(counter?Sg-1)*8],xmm0
; else
; mov[rsp+size@frame+(counter?Sg-1)*8],rax
; end if
; else
; flags?Sh=flags?Sh or 1 shl(counter?Sg-1)
; if isfloat?St
; flags?Sh=flags?Sh or 1 shl(4+counter?Sg-1)
; end if
; if ..close_nest?Sk>..next?Su
; if float
; movq[rsp+size@frame+(counter?Sg-1)*8],xmm0
; else
; mov[rsp+size@frame+(counter?Sg-1)*8],rax
; end if
; else
; flags?Sh=flags?Sh or 1 shl(8+counter?Sg-1)
; end if
; end if
; ..next?Su:}
;list?Sf equ<'%sstart str_to_malloc',13,10>,<spaces>

..close_nest?Sk:
;match,nested_frame?Sj{endf}
if flags?Sh and 1
if flags?Sh and 1 shl 4
if~flags?Sh and 1 shl 8
movq xmm0,[rsp]
end if
else
if flags?Sh and 1 shl 8
mov rcx,rax
else
mov rcx,[rsp]
end if
end if
end if
if flags?Sh and 1 shl 1
if flags?Sh and 1 shl(4+1)
if flags?Sh and 1 shl(8+1)
movq xmm1,xmm0
else
movq xmm1,[rsp+8]
end if
else
if flags?Sh and 1 shl(8+1)
mov rdx,rax
else
mov rdx,[rsp+8]
end if
end if
end if
if flags?Sh and 1 shl 2
if flags?Sh and 1 shl(4+2)
if flags?Sh and 1 shl(8+2)
movq xmm2,xmm0
else
movq xmm2,[rsp+2*8]
end if
else
if flags?Sh and 1 shl(8+2)
mov r8,rax
else
mov r8,[rsp+2*8]
end if
end if
end if
if flags?Sh and 1 shl 3
if flags?Sh and 1 shl(4+3)
if flags?Sh and 1 shl(8+3)
movq xmm3,xmm0
else
movq xmm3,[rsp+3*8]
end if
else
if flags?Sh and 1 shl(8+3)
mov r9,rax
else
mov r9,[rsp+3*8]
end if
end if
end if
;match args,<'%sstart str_to_malloc',13,10>,<spaces>{fastcall[printf],args}
;fastcall[printf],<'%sstart str_to_malloc',13,10>,<spaces>


; stackspace?Sv argscount?Sw counter?Sx
if argscount?Sw<4
stackspace?Sv=4*8
else if argscount?Sw and 1
stackspace?Sv=(argscount?Sw+1)*8
else
stackspace?Sv=argscount?Sw*8
end if
counter?Sx=0
if stackspace?Sv
if defined current?Sm
if current?Sm<stackspace?Sv
current?Sm=stackspace?Sv
end if
else
if stackspace?Sv
sub rsp,stackspace?Sv
end if
end if
end if

counter?Sx=counter?Sx+1
;define type@param
;define definition@param '%sstart str_to_malloc',13,10
;match=float value,'%sstart str_to_malloc',13,10
;{define definition@param value
; define type@param float}
;match=addr value,'%sstart str_to_malloc',13,10
;{define definition@param value
; define type@param addr}
;match any=,any,'%sstart str_to_malloc',13,10
;{local ..string,..continue
; jmp ..continue
; align sizeof.TCHAR
; ..string TCHAR definition@param,0
; ..continue:
; define definition@param ..string
; define type@param addr}
; ..string?Sy ..continue?Sz
jmp ..continue?Sz
align sizeof.TCHAR
;..string?Sy:;TCHAR definition@param,0


;match any,'%sstart str_to_malloc',13,10,0{..string?Sy du definition@param,0}
..string?Sy du '%sstart str_to_malloc',13,10,0
;match,'%sstart str_to_malloc',13,10,0{..string?Sy du ?}
..continue?Sz:
;define definition@param ..string?Sy
;define type@param addr
;match any,..string?Sy
;{match`any,any
; \{ \local ..string,..continue
; jmp ..continue
; align sizeof.TCHAR
; ..string TCHAR definition@param,0
; ..continue:
; define definition@param ..string
; define type@param addr \}}
;match '..string?Sy',..string?Sy
;{local ..string,..continue
; jmp ..continue
; align sizeof.TCHAR
; ..string TCHAR definition@param,0
; ..continue:
; define definition@param ..string
; define type@param addr}
;match param,..string?Sy
;{local opcode,origin
; size@param=0
; if param eqtype 0|param eqtype 0f|type@param eq addr
; size@param=8
; else if param eqtype byte 0|param eqtype byte 0f
; match prefix value,definition@param
; \{ if prefix eq qword
; size@param=8
; else if prefix eq dword
; size@param=4
; else if prefix eq word
; size@param=2
; else if prefix eq byte
; size@param=1
; end if \}
; else if~param in<xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15>
; virtual
; origin=$
; inc param
; load opcode byte from origin
; if opcode=67h|opcode=41h
; load opcode byte from origin+1
; end if
; if opcode and 0F8h=48h
; size@param=8
; else if opcode=66h
; size@param=2
; else if opcode=0FFh
; size@param=4
; else
; size@param=1
; end if
; end virtual
; end if
; if counter?Sx=1
; if type@param eq float
; if~param eq xmm0
; if size@param=4
; if param eqtype byte 0|param eqtype byte 0f
; mov eax,param
; movd xmm0,eax
; else
; movd xmm0,param
; end if
; else
; if param eqtype 0|param eqtype 0f|param eqtype byte 0|param eqtype byte 0f
; mov rax,param
; movq xmm0,rax
; else
; movq xmm0,param
; end if
; end if
; end if
; if vararg@fastcall&~param eq rcx
; movq rcx,xmm0
; end if
; else if type@param eq addr
; if~param eq rcx
; lea rcx,[param]
; end if
; else if size@param=8
; if~param eq rcx
; mov rcx,param
; end if
; else if size@param=4
; if~param eq ecx
; mov ecx,param
; end if
; else if size@param=2
; if~param eq cx
; mov cx,param
; end if
; else if size@param=1
; if~param eq cl
; mov cl,param
; end if
; end if
; else if counter?Sx=2
; if type@param eq float
; if~param eq xmm1
; if size@param=4
; if param eqtype byte 0|param eqtype byte 0f
; mov eax,param
; movd xmm1,eax
; else
; movd xmm1,param
; end if
; else
; if param eqtype 0|param eqtype 0f|param eqtype byte 0|param eqtype byte 0f
; mov rax,param
; movq xmm1,rax
; else
; movq xmm1,param
; end if
; end if
; end if
; if vararg@fastcall&~param eq rdx
; movq rdx,xmm1
; end if
; else if type@param eq addr
; if~param eq rdx
; lea rdx,[param]
; end if
; else if size@param=8
; if~param eq rdx
; mov rdx,param
; end if
; else if size@param=4
; if~param eq edx
; mov edx,param
; end if
; else if size@param=2
; if~param eq dx
; mov dx,param
; end if
; else if size@param=1
; if~param eq dl
; mov dl,param
; end if
; end if
; else if counter?Sx=3
; if type@param eq float
; if~param eq xmm2
; if size@param=4
; if param eqtype byte 0|param eqtype byte 0f
; mov eax,param
; movd xmm2,eax
; else
; movd xmm2,param
; end if
; else
; if param eqtype 0|param eqtype 0f|param eqtype byte 0|param eqtype byte 0f
; mov rax,param
; movq xmm2,rax
; else
; movq xmm2,param
; end if
; end if
; end if
; if vararg@fastcall&~param eq r8
; movq r8,xmm2
; end if
; else if type@param eq addr
; if~param eq r8
; lea r8,[param]
; end if
; else if size@param=8
; if~param eq r8
; mov r8,param
; end if
; else if size@param=4
; if~param eq r8d
; mov r8d,param
; end if
; else if size@param=2
; if~param eq r8w
; mov r8w,param
; end if
; else if size@param=1
; if~param eq r8b
; mov r8b,param
; end if
; end if
; else if counter?Sx=4
; if type@param eq float
; if~param eq xmm3
; if size@param=4
; if param eqtype byte 0|param eqtype byte 0f
; mov eax,param
; movd xmm3,eax
; else
; movd xmm3,param
; end if
; else
; if param eqtype 0|param eqtype 0f|param eqtype byte 0|param eqtype byte 0f
; mov rax,param
; movq xmm3,rax
; else
; movq xmm3,param
; end if
; end if
; end if
; if vararg@fastcall&~param eq r9
; movq r9,xmm3
; end if
; else if type@param eq addr
; if~param eq r9
; lea r9,[param]
; end if
; else if size@param=8
; if~param eq r9
; mov r9,param
; end if
; else if size@param=4
; if~param eq r9d
; mov r9d,param
; end if
; else if size@param=2
; if~param eq r9w
; mov r9w,param
; end if
; else if size@param=1
; if~param eq r9b
; mov r9b,param
; end if
; end if
; else
; if type@param eq addr
; lea rax,[param]
; mov[rsp+(counter?Sx-1)*8],rax
; else if param eqtype[0]|param eqtype byte[0]
; if size@param=8
; mov rax,param
; mov[rsp+(counter?Sx-1)*8],rax
; else if size@param=4
; mov eax,param
; mov[rsp+(counter?Sx-1)*8],eax
; else if size@param=2
; mov ax,param
; mov[rsp+(counter?Sx-1)*8],ax
; else
; mov al,param
; mov[rsp+(counter?Sx-1)*8],al
; end if
; else if size@param=8
; virtual
; origin=$
; mov rax,param
; load opcode byte from origin+1
; end virtual
; if opcode=0B8h
; mov rax,param
; mov[rsp+(counter?Sx-1)*8],rax
; else
; mov qword[rsp+(counter?Sx-1)*8],param
; end if
; else if param in<xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15>
; movq[rsp+(counter?Sx-1)*8],param
; else
; mov[rsp+(counter?Sx-1)*8],param
; end if
; end if}
; opcode?T0 origin?T1
size@param=0
if ..string?Sy eqtype 0|..string?Sy eqtype 0f|addr eq addr
size@param=8
else if ..string?Sy eqtype byte 0|..string?Sy eqtype byte 0f
;match prefix value,..string?Sy
;{if prefix eq qword
; size@param=8
; else if prefix eq dword
; size@param=4
; else if prefix eq word
; size@param=2
; else if prefix eq byte
; size@param=1
; end if}
else if~..string?Sy in<xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15>
virtual
origin?T1=$
inc ..string?Sy
load opcode?T0 byte from origin?T1
if opcode?T0=67h|opcode?T0=41h
load opcode?T0 byte from origin?T1+1
end if
if opcode?T0 and 0F8h=48h
size@param=8
else if opcode?T0=66h
size@param=2
else if opcode?T0=0FFh
size@param=4
else
size@param=1
end if
end virtual
end if
if counter?Sx=1
if addr eq float
if~..string?Sy eq xmm0
if size@param=4
if ..string?Sy eqtype byte 0|..string?Sy eqtype byte 0f
mov eax,..string?Sy
movd xmm0,eax
else
movd xmm0,..string?Sy
end if
else
if ..string?Sy eqtype 0|..string?Sy eqtype 0f|..string?Sy eqtype byte 0|..string?Sy eqtype byte 0f
mov rax,..string?Sy
movq xmm0,rax
else
movq xmm0,..string?Sy
end if
end if
end if
if vararg@fastcall&~..string?Sy eq rcx
movq rcx,xmm0
end if
else if addr eq addr
if~..string?Sy eq rcx
lea rcx,[..string?Sy]
end if
else if size@param=8
if~..string?Sy eq rcx
mov rcx,..string?Sy
end if
else if size@param=4
if~..string?Sy eq ecx
mov ecx,..string?Sy
end if
else if size@param=2
if~..string?Sy eq cx
mov cx,..string?Sy
end if
else if size@param=1
if~..string?Sy eq cl
mov cl,..string?Sy
end if
end if
else if counter?Sx=2
if addr eq float
if~..string?Sy eq xmm1
if size@param=4
if ..string?Sy eqtype byte 0|..string?Sy eqtype byte 0f
mov eax,..string?Sy
movd xmm1,eax
else
movd xmm1,..string?Sy
end if
else
if ..string?Sy eqtype 0|..string?Sy eqtype 0f|..string?Sy eqtype byte 0|..string?Sy eqtype byte 0f
mov rax,..string?Sy
movq xmm1,rax
else
movq xmm1,..string?Sy
end if
end if
end if
if vararg@fastcall&~..string?Sy eq rdx
movq rdx,xmm1
end if
else if addr eq addr
if~..string?Sy eq rdx
lea rdx,[..string?Sy]
end if
else if size@param=8
if~..string?Sy eq rdx
mov rdx,..string?Sy
end if
else if size@param=4
if~..string?Sy eq edx
mov edx,..string?Sy
end if
else if size@param=2
if~..string?Sy eq dx
mov dx,..string?Sy
end if
else if size@param=1
if~..string?Sy eq dl
mov dl,..string?Sy
end if
end if
else if counter?Sx=3
if addr eq float
if~..string?Sy eq xmm2
if size@param=4
if ..string?Sy eqtype byte 0|..string?Sy eqtype byte 0f
mov eax,..string?Sy
movd xmm2,eax
else
movd xmm2,..string?Sy
end if
else
if ..string?Sy eqtype 0|..string?Sy eqtype 0f|..string?Sy eqtype byte 0|..string?Sy eqtype byte 0f
mov rax,..string?Sy
movq xmm2,rax
else
movq xmm2,..string?Sy
end if
end if
end if
if vararg@fastcall&~..string?Sy eq r8
movq r8,xmm2
end if
else if addr eq addr
if~..string?Sy eq r8
lea r8,[..string?Sy]
end if
else if size@param=8
if~..string?Sy eq r8
mov r8,..string?Sy
end if
else if size@param=4
if~..string?Sy eq r8d
mov r8d,..string?Sy
end if
else if size@param=2
if~..string?Sy eq r8w
mov r8w,..string?Sy
end if
else if size@param=1
if~..string?Sy eq r8b
mov r8b,..string?Sy
end if
end if
else if counter?Sx=4
if addr eq float
if~..string?Sy eq xmm3
if size@param=4
if ..string?Sy eqtype byte 0|..string?Sy eqtype byte 0f
mov eax,..string?Sy
movd xmm3,eax
else
movd xmm3,..string?Sy
end if
else
if ..string?Sy eqtype 0|..string?Sy eqtype 0f|..string?Sy eqtype byte 0|..string?Sy eqtype byte 0f
mov rax,..string?Sy
movq xmm3,rax
else
movq xmm3,..string?Sy
end if
end if
end if
if vararg@fastcall&~..string?Sy eq r9
movq r9,xmm3
end if
else if addr eq addr
if~..string?Sy eq r9
lea r9,[..string?Sy]
end if
else if size@param=8
if~..string?Sy eq r9
mov r9,..string?Sy
end if
else if size@param=4
if~..string?Sy eq r9d
mov r9d,..string?Sy
end if
else if size@param=2
if~..string?Sy eq r9w
mov r9w,..string?Sy
end if
else if size@param=1
if~..string?Sy eq r9b
mov r9b,..string?Sy
end if
end if
else
if addr eq addr
lea rax,[..string?Sy]
mov[rsp+(counter?Sx-1)*8],rax
else if ..string?Sy eqtype[0]|..string?Sy eqtype byte[0]
if size@param=8
mov rax,..string?Sy
mov[rsp+(counter?Sx-1)*8],rax
else if size@param=4
mov eax,..string?Sy
mov[rsp+(counter?Sx-1)*8],eax
else if size@param=2
mov ax,..string?Sy
mov[rsp+(counter?Sx-1)*8],ax
else
mov al,..string?Sy
mov[rsp+(counter?Sx-1)*8],al
end if
else if size@param=8
virtual
origin?T1=$
mov rax,..string?Sy
load opcode?T0 byte from origin?T1+1
end virtual
if opcode?T0=0B8h
mov rax,..string?Sy
mov[rsp+(counter?Sx-1)*8],rax
else
mov qword[rsp+(counter?Sx-1)*8],..string?Sy
end if
else if ..string?Sy in<xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15>
movq[rsp+(counter?Sx-1)*8],..string?Sy
else
mov[rsp+(counter?Sx-1)*8],..string?Sy
end if
end if

counter?Sx=counter?Sx+1
;define type@param
;define definition@param spaces
;match=float value,spaces
;{define definition@param value
; define type@param float}
;match=addr value,spaces
;{define definition@param value
; define type@param addr}
;match any=,any,spaces
;{local ..string,..continue
; jmp ..continue
; align sizeof.TCHAR
; ..string TCHAR definition@param,0
; ..continue:
; define definition@param ..string
; define type@param addr}
;match any,spaces
;{match`any,any
; \{ \local ..string,..continue
; jmp ..continue
; align sizeof.TCHAR
; ..string TCHAR definition@param,0
; ..continue:
; define definition@param ..string
; define type@param addr \}}
;match 'spaces',spaces
;{local ..string,..continue
; jmp ..continue
; align sizeof.TCHAR
; ..string TCHAR definition@param,0
; ..continue:
; define definition@param ..string
; define type@param addr}
;match param,spaces
;{local opcode,origin
; size@param=0
; if param eqtype 0|param eqtype 0f|type@param eq addr
; size@param=8
; else if param eqtype byte 0|param eqtype byte 0f
; match prefix value,definition@param
; \{ if prefix eq qword
; size@param=8
; else if prefix eq dword
; size@param=4
; else if prefix eq word
; size@param=2
; else if prefix eq byte
; size@param=1
; end if \}
; else if~param in<xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15>
; virtual
; origin=$
; inc param
; load opcode byte from origin
; if opcode=67h|opcode=41h
; load opcode byte from origin+1
; end if
; if opcode and 0F8h=48h
; size@param=8
; else if opcode=66h
; size@param=2
; else if opcode=0FFh
; size@param=4
; else
; size@param=1
; end if
; end virtual
; end if
; if counter?Sx=1
; if type@param eq float
; if~param eq xmm0
; if size@param=4
; if param eqtype byte 0|param eqtype byte 0f
; mov eax,param
; movd xmm0,eax
; else
; movd xmm0,param
; end if
; else
; if param eqtype 0|param eqtype 0f|param eqtype byte 0|param eqtype byte 0f
; mov rax,param
; movq xmm0,rax
; else
; movq xmm0,param
; end if
; end if
; end if
; if vararg@fastcall&~param eq rcx
; movq rcx,xmm0
; end if
; else if type@param eq addr
; if~param eq rcx
; lea rcx,[param]
; end if
; else if size@param=8
; if~param eq rcx
; mov rcx,param
; end if
; else if size@param=4
; if~param eq ecx
; mov ecx,param
; end if
; else if size@param=2
; if~param eq cx
; mov cx,param
; end if
; else if size@param=1
; if~param eq cl
; mov cl,param
; end if
; end if
; else if counter?Sx=2
; if type@param eq float
; if~param eq xmm1
; if size@param=4
; if param eqtype byte 0|param eqtype byte 0f
; mov eax,param
; movd xmm1,eax
; else
; movd xmm1,param
; end if
; else
; if param eqtype 0|param eqtype 0f|param eqtype byte 0|param eqtype byte 0f
; mov rax,param
; movq xmm1,rax
; else
; movq xmm1,param
; end if
; end if
; end if
; if vararg@fastcall&~param eq rdx
; movq rdx,xmm1
; end if
; else if type@param eq addr
; if~param eq rdx
; lea rdx,[param]
; end if
; else if size@param=8
; if~param eq rdx
; mov rdx,param
; end if
; else if size@param=4
; if~param eq edx
; mov edx,param
; end if
; else if size@param=2
; if~param eq dx
; mov dx,param
; end if
; else if size@param=1
; if~param eq dl
; mov dl,param
; end if
; end if
; else if counter?Sx=3
; if type@param eq float
; if~param eq xmm2
; if size@param=4
; if param eqtype byte 0|param eqtype byte 0f
; mov eax,param
; movd xmm2,eax
; else
; movd xmm2,param
; end if
; else
; if param eqtype 0|param eqtype 0f|param eqtype byte 0|param eqtype byte 0f
; mov rax,param
; movq xmm2,rax
; else
; movq xmm2,param
; end if
; end if
; end if
; if vararg@fastcall&~param eq r8
; movq r8,xmm2
; end if
; else if type@param eq addr
; if~param eq r8
; lea r8,[param]
; end if
; else if size@param=8
; if~param eq r8
; mov r8,param
; end if
; else if size@param=4
; if~param eq r8d
; mov r8d,param
; end if
; else if size@param=2
; if~param eq r8w
; mov r8w,param
; end if
; else if size@param=1
; if~param eq r8b
; mov r8b,param
; end if
; end if
; else if counter?Sx=4
; if type@param eq float
; if~param eq xmm3
; if size@param=4
; if param eqtype byte 0|param eqtype byte 0f
; mov eax,param
; movd xmm3,eax
; else
; movd xmm3,param
; end if
; else
; if param eqtype 0|param eqtype 0f|param eqtype byte 0|param eqtype byte 0f
; mov rax,param
; movq xmm3,rax
; else
; movq xmm3,param
; end if
; end if
; end if
; if vararg@fastcall&~param eq r9
; movq r9,xmm3
; end if
; else if type@param eq addr
; if~param eq r9
; lea r9,[param]
; end if
; else if size@param=8
; if~param eq r9
; mov r9,param
; end if
; else if size@param=4
; if~param eq r9d
; mov r9d,param
; end if
; else if size@param=2
; if~param eq r9w
; mov r9w,param
; end if
; else if size@param=1
; if~param eq r9b
; mov r9b,param
; end if
; end if
; else
; if type@param eq addr
; lea rax,[param]
; mov[rsp+(counter?Sx-1)*8],rax
; else if param eqtype[0]|param eqtype byte[0]
; if size@param=8
; mov rax,param
; mov[rsp+(counter?Sx-1)*8],rax
; else if size@param=4
; mov eax,param
; mov[rsp+(counter?Sx-1)*8],eax
; else if size@param=2
; mov ax,param
; mov[rsp+(counter?Sx-1)*8],ax
; else
; mov al,param
; mov[rsp+(counter?Sx-1)*8],al
; end if
; else if size@param=8
; virtual
; origin=$
; mov rax,param
; load opcode byte from origin+1
; end virtual
; if opcode=0B8h
; mov rax,param
; mov[rsp+(counter?Sx-1)*8],rax
; else
; mov qword[rsp+(counter?Sx-1)*8],param
; end if
; else if param in<xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15>
; movq[rsp+(counter?Sx-1)*8],param
; else
; mov[rsp+(counter?Sx-1)*8],param
; end if
; end if}
; opcode?T2 origin?T3
size@param=0
if spaces eqtype 0|spaces eqtype 0f|eq addr
size@param=8
else if spaces eqtype byte 0|spaces eqtype byte 0f
;match prefix value,spaces
;{if prefix eq qword
; size@param=8
; else if prefix eq dword
; size@param=4
; else if prefix eq word
; size@param=2
; else if prefix eq byte
; size@param=1
; end if}
else if~spaces in<xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15>
virtual
origin?T3=$
inc spaces
load opcode?T2 byte from origin?T3
if opcode?T2=67h|opcode?T2=41h
load opcode?T2 byte from origin?T3+1
end if
if opcode?T2 and 0F8h=48h
size@param=8
else if opcode?T2=66h
size@param=2
else if opcode?T2=0FFh
size@param=4
else
size@param=1
end if
end virtual
end if
if counter?Sx=1
if eq float
if~spaces eq xmm0
if size@param=4
if spaces eqtype byte 0|spaces eqtype byte 0f
mov eax,spaces
movd xmm0,eax
else
movd xmm0,spaces
end if
else
if spaces eqtype 0|spaces eqtype 0f|spaces eqtype byte 0|spaces eqtype byte 0f
mov rax,spaces
movq xmm0,rax
else
movq xmm0,spaces
end if
end if
end if
if vararg@fastcall&~spaces eq rcx
movq rcx,xmm0
end if
else if eq addr
if~spaces eq rcx
lea rcx,[spaces]
end if
else if size@param=8
if~spaces eq rcx
mov rcx,spaces
end if
else if size@param=4
if~spaces eq ecx
mov ecx,spaces
end if
else if size@param=2
if~spaces eq cx
mov cx,spaces
end if
else if size@param=1
if~spaces eq cl
mov cl,spaces
end if
end if
else if counter?Sx=2
if eq float
if~spaces eq xmm1
if size@param=4
if spaces eqtype byte 0|spaces eqtype byte 0f
mov eax,spaces
movd xmm1,eax
else
movd xmm1,spaces
end if
else
if spaces eqtype 0|spaces eqtype 0f|spaces eqtype byte 0|spaces eqtype byte 0f
mov rax,spaces
movq xmm1,rax
else
movq xmm1,spaces
end if
end if
end if
if vararg@fastcall&~spaces eq rdx
movq rdx,xmm1
end if
else if eq addr
if~spaces eq rdx
lea rdx,[spaces]
end if
else if size@param=8
if~spaces eq rdx
mov rdx,spaces
end if
else if size@param=4
if~spaces eq edx
mov edx,spaces
end if
else if size@param=2
if~spaces eq dx
mov dx,spaces
end if
else if size@param=1
if~spaces eq dl
mov dl,spaces
end if
end if
else if counter?Sx=3
if eq float
if~spaces eq xmm2
if size@param=4
if spaces eqtype byte 0|spaces eqtype byte 0f
mov eax,spaces
movd xmm2,eax
else
movd xmm2,spaces
end if
else
if spaces eqtype 0|spaces eqtype 0f|spaces eqtype byte 0|spaces eqtype byte 0f
mov rax,spaces
movq xmm2,rax
else
movq xmm2,spaces
end if
end if
end if
if vararg@fastcall&~spaces eq r8
movq r8,xmm2
end if
else if eq addr
if~spaces eq r8
lea r8,[spaces]
end if
else if size@param=8
if~spaces eq r8
mov r8,spaces
end if
else if size@param=4
if~spaces eq r8d
mov r8d,spaces
end if
else if size@param=2
if~spaces eq r8w
mov r8w,spaces
end if
else if size@param=1
if~spaces eq r8b
mov r8b,spaces
end if
end if
else if counter?Sx=4
if eq float
if~spaces eq xmm3
if size@param=4
if spaces eqtype byte 0|spaces eqtype byte 0f
mov eax,spaces
movd xmm3,eax
else
movd xmm3,spaces
end if
else
if spaces eqtype 0|spaces eqtype 0f|spaces eqtype byte 0|spaces eqtype byte 0f
mov rax,spaces
movq xmm3,rax
else
movq xmm3,spaces
end if
end if
end if
if vararg@fastcall&~spaces eq r9
movq r9,xmm3
end if
else if eq addr
if~spaces eq r9
lea r9,[spaces]
end if
else if size@param=8
if~spaces eq r9
mov r9,spaces
end if
else if size@param=4
if~spaces eq r9d
mov r9d,spaces
end if
else if size@param=2
if~spaces eq r9w
mov r9w,spaces
end if
else if size@param=1
if~spaces eq r9b
mov r9b,spaces
end if
end if
else
if eq addr
lea rax,[spaces]
mov[rsp+(counter?Sx-1)*8],rax
else if spaces eqtype[0]|spaces eqtype byte[0]
if size@param=8
mov rax,spaces
mov[rsp+(counter?Sx-1)*8],rax
else if size@param=4
mov eax,spaces
mov[rsp+(counter?Sx-1)*8],eax
else if size@param=2
mov ax,spaces
mov[rsp+(counter?Sx-1)*8],ax
else
mov al,spaces
mov[rsp+(counter?Sx-1)*8],al
end if
else if size@param=8
virtual
origin?T3=$
mov rax,spaces
load opcode?T2 byte from origin?T3+1
end virtual
if opcode?T2=0B8h
mov rax,spaces
mov[rsp+(counter?Sx-1)*8],rax
else
mov qword[rsp+(counter?Sx-1)*8],spaces
end if
else if spaces in<xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15>
movq[rsp+(counter?Sx-1)*8],spaces
else
mov[rsp+(counter?Sx-1)*8],spaces
end if
end if

argscount?Sw=counter?Sx
call[printf]
if stackspace?Sv&~defined current?Sm
add rsp,stackspace?Sv
end if
;match,<'%sstart str_to_malloc',13,10>,<spaces>{fastcall[printf]}
;match,{endf}
;endf
size?Sl=current?Sm
if size?Sl
add rsp,size?Sl
end if
;restore size@frame,current@frame
vararg@fastcall=0    
If your code is generated, then perhaps a better choice would be to use generated sequences for fastcall instead of relying on a huge macro.
Post 08 Dec 2019, 10:35
View user's profile Send private message Visit poster's website Reply with quote
DimonSoft



Joined: 03 Mar 2010
Posts: 655
Location: Belarus
DimonSoft
As somewhat related stuff, I’ve just tried to build a 512 MB file with FASM 1.73.21 (latest version). Compiler memory was set to 1'048'576. The project uses a lot of macros and assembler stage calculations. The file is mostly padded with zero bytes at the end. I got a wrong value at the beginning of the file. The value is calculated from %t. Doesn’t reproduce anymore though.

The code is quite simple and well-tested. I definitely can’t be sure it’s not my bug, but I guess this might be some out-of-bounds bug in FASM that manifests itself in such conditions. Just wanted to let you know.
Post 08 Dec 2019, 16:21
View user's profile Send private message Visit poster's website Reply with quote
DSblizzard



Joined: 23 Oct 2019
Posts: 15
Location: Ryazan, Russia
DSblizzard
I removed cinvokes and now fasm uses < 100 MB of memory and assembles in 1.2 sec - 10 times less than before. Thank you, Tomasz.
Post 09 Dec 2019, 08:36
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-2020, Tomasz Grysztar.

Powered by rwasa.