flat assembler
Message board for the users of flat assembler.
Index
> Compiler Internals > Listing tool feature request |
Author |
|
LocoDelAssembly 29 Jun 2009, 15:06
Tomasz, do you have any plans to provide an option to output a listing more like http://board.flatassembler.net/topic.php?t=5764 ? (Showing CPU-level instructions instead of macro invocations, etc)
Code: 0000000000401000: 55 push rbp 0000000000401001: 48 89 E5 mov rbp, rsp 0000000000401004: 48 81 EC 00 04 00 00 sub rsp, localbytes?cf + alignment?cj 000000000040100B: 48 8D 95 00 FC FF FF lea rdx, [ TempStr ] 0000000000401012: 48 83 EC 10 sub rsp, stackspace?d7 0000000000401016: 48 89 D1 mov rcx, rdx 0000000000401019: 48 8B 55 10 mov rdx, [ _String ] 000000000040101D: FF 15 06 00 00 00 call [ lstrcpy ] 0000000000401023: 48 83 C4 10 add rsp, stackspace?d7 0000000000401027: C9 leave 0000000000401028: C3 retn 0000000000401029: 00 00 00 00 00 00 00 00 lstrcpy dq 0 Instead of: Code: ; LOTS OF LINES ABOVE entry Function 00000200: 55 48 89 E5 48 81 EC 00 04 00 00 proc Function, _String local TempStr[1024]:BYTE 0000020B: 48 8D 95 00 FC FF FF lea rdx, [TempStr] 00000212: 48 83 EC 10 48 89 D1 48 8B 55 10 FF 15 06 00 00 invoke lstrcpy, rdx, [_String] 00 48 83 C4 10 00000227: C9 C3 ret endp 00000229: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 lstrcpy dq 0 Or: Code: format PE64 GUI entry Function ;proc Function,_String ;match name params,Function,_String> ;{define@proc name,<params} ;define@proc Function,<,_String> ; params?Qz flag?R0 regs?R1 parmbytes?R2 localbytes?R3 current?R4 if used Function Function: ;match=stdcall args,,_String{params?Qz equ args ; flag?R0=11b} ;match=stdcall,,_String{params?Qz equ ; flag?R0=11b} ;match=c args,,_String{params?Qz equ args ; flag?R0=10001b} ;match=c,,_String{params?Qz equ ; flag?R0=10001b} ;match=params?Qz,params?Qz{params?Qz equ,_String ; flag?R0=10000b} ;params?Qz equ,_String flag?R0=10000b virtual at rbp+16 ;match=uses reglist=,args,,_String{regs?R1 equ reglist ; params?Qz equ args} ;match=regs?R1=uses reglist,regs?R1,_String{regs?R1 equ reglist ; params?Qz equ} ;match=regs?R1,regs?R1{regs?R1 equ} ;regs?R1 equ ;match=,args,,_String{defargs@proc args} ;defargs@proc _String if~_String eq ; ..arg?R5 current@arg?R6 ;match argname:type,_String ;{current@arg?R6 equ argname ; label ..arg?R5 type ; argname equ ..arg?R5 ; if dqword eq type ; dq ?,? ; else if tbyte eq type ; dq ?,? ; else ; dq ? ; end if} ;match=current@arg?R6,current@arg?R6 ;{current@arg?R6 equ _String ; _String equ ..arg?R5 ; ..arg?R5 dq ?} ;current@arg?R6 equ _String ;_String equ ..arg?R5 ..arg?R5 dq ? ;args@proc equ _String ;restore current@arg?R6 end if ;match=args@proc args,_String,_String{defargs@proc args} parmbytes?R2=$-(rbp+16) end virtual Function%=parmbytes?R2/8 ;all@vars equ current?R4=0 ;match prologue:reglist,prologuedef:<>{prologue Function,flag?R0,parmbytes?R2,localbytes?R3,reglist} ;prologuedef Function,flag?R0,parmbytes?R2,localbytes?R3,<> ; alignment?R7 counter?R8 if parmbytes?R2|localbytes?R3 push rbp mov rbp,rsp if localbytes?R3+alignment?R7 sub rsp,localbytes?R3+alignment?R7 end if end if counter?R8=0 ;irps reg,{push reg ; counter?R8=counter?R8+1} alignment?R7=8*(counter?R8 and 1) ;macro locals ;{virtual at rbp-localbytes?R3+current?R4 ; macro label def \{ match . type,def>\\{ deflocal@proc .,label,<type \\} \} ; struc db[val]\{ common deflocal@proc .,db,val \} ; struc du[val]\{ common deflocal@proc .,du,val \} ; struc dw[val]\{ common deflocal@proc .,dw,val \} ; struc dp[val]\{ common deflocal@proc .,dp,val \} ; struc dd[val]\{ common deflocal@proc .,dd,val \} ; struc dt[val]\{ common deflocal@proc .,dt,val \} ; struc dq[val]\{ common deflocal@proc .,dq,val \} ; struc rb cnt \{ deflocal@proc .,rb cnt,\} ; struc rw cnt \{ deflocal@proc .,rw cnt,\} ; struc rp cnt \{ deflocal@proc .,rp cnt,\} ; struc rd cnt \{ deflocal@proc .,rd cnt,\} ; struc rt cnt \{ deflocal@proc .,rt cnt,\} ; struc rq cnt \{ deflocal@proc .,rq cnt,\}} ;macro endl ;{purge label ; restruc db,du,dw,dp,dd,dt,dq ; restruc rb,rw,rp,rd,rt,rq ; current?R4=$-(rbp-localbytes?R3) ; end virtual} ;macro ret operand ;{match any,operand \{ retn operand \} ; match,operand \{ match epilogue:reglist,epilogue@proc:<regs?R1> ; \\{ epilogue Function,flag?R0,parmbytes?R2,localbytes?R3,reglist \\} \}} ;macro finish@proc{localbytes?R3=(current?R4+15)and(not 15) ; end if} ;local TempStr[1024]:BYTE ;locals virtual at rbp-localbytes?R3+current?R4 ;macro label def{match . type,def>\{ deflocal@proc .,label,<type \}} ;struc db[val]{common deflocal@proc .,db,val} ;struc du[val]{common deflocal@proc .,du,val} ;struc dw[val]{common deflocal@proc .,dw,val} ;struc dp[val]{common deflocal@proc .,dp,val} ;struc dd[val]{common deflocal@proc .,dd,val} ;struc dt[val]{common deflocal@proc .,dt,val} ;struc dq[val]{common deflocal@proc .,dq,val} ;struc rb cnt{deflocal@proc .,rb cnt,} ;struc rw cnt{deflocal@proc .,rw cnt,} ;struc rp cnt{deflocal@proc .,rp cnt,} ;struc rd cnt{deflocal@proc .,rd cnt,} ;struc rt cnt{deflocal@proc .,rt cnt,} ;struc rq cnt{deflocal@proc .,rq cnt,} ;done@local equ ;match varname[count]:vartype,TempStr[1024]:BYTE ;{match=BYTE,vartype \{ varname rb count ; restore done@local \} ; match=WORD,vartype \{ varname rw count ; restore done@local \} ; match=DWORD,vartype \{ varname rd count ; restore done@local \} ; match=PWORD,vartype \{ varname rp count ; restore done@local \} ; match=QWORD,vartype \{ varname rq count ; restore done@local \} ; match=TBYTE,vartype \{ varname rt count ; restore done@local \} ; match=DQWORD,vartype \{ label varname dqword ; rq count+count ; restore done@local \} ; match,done@local \{ virtual ; varname vartype ; end virtual ; rb count*sizeof.#vartype ; restore done@local \}} ;match=BYTE,BYTE{TempStr rb 1024 ; restore done@local} ;TempStr:;rb 1024 ;deflocal@proc TempStr,rb 1024, ;match vars,{all@vars equ all@vars,} ;all@vars equ TempStr ; ..var?R9 ..tmp?RA ;match=label,rb 1024{..tmp?RA equ} ;match tmp,..tmp?RA{..var?R9 rb 1024} ..var?R9 rb 1024 ;match,..tmp?RA{label ..var?R9} ;match=?,{..tmp?RA equ} ;match any=?,{..tmp?RA equ} ;match any(=?),{..tmp?RA equ} ;match tmp:value,..tmp?RA: ;{tmp:end virtual ; initlocal@proc ..var?R9,rb 1024 value ; virtual at tmp} ;match first rest,..var?R9,{TempStr equ first} ;TempStr equ ..var?R9 ;restore done@local ;match=WORD,BYTE{TempStr rw 1024 ; restore done@local} ;match=DWORD,BYTE{TempStr rd 1024 ; restore done@local} ;match=PWORD,BYTE{TempStr rp 1024 ; restore done@local} ;match=QWORD,BYTE{TempStr rq 1024 ; restore done@local} ;match=TBYTE,BYTE{TempStr rt 1024 ; restore done@local} ;match=DQWORD,BYTE{label TempStr dqword ; rq 1024+1024 ; restore done@local} ;match,done@local{virtual ; TempStr BYTE ; end virtual ; rb 1024*sizeof.BYTE ; restore done@local} ;match:varname:vartype,done@local:..var?R9[1024]:BYTE ;{match=BYTE,vartype \{ varname db ? ; restore done@local \} ; match=WORD,vartype \{ varname dw ? ; restore done@local \} ; match=DWORD,vartype \{ varname dd ? ; restore done@local \} ; match=PWORD,vartype \{ varname dp ? ; restore done@local \} ; match=QWORD,vartype \{ varname dq ? ; restore done@local \} ; match=TBYTE,vartype \{ varname dt ? ; restore done@local \} ; match=DQWORD,vartype \{ label varname dqword ; dq ?,? ; restore done@local \} ; match,done@local \{ varname vartype ; restore done@local \}} ;match,done@local ;{TempStr[1024]:BYTE ; restore done@local} ;endl ;purge label ;restruc db,du,dw,dp,dd,dt,dq ;restruc rb,rw,rp,rd,rt,rq current?R4=$-(rbp-localbytes?R3) end virtual lea rdx,[..var?R9] ;invoke lstrcpy,rdx,[_String] ;fastcall[lstrcpy],rdx,[_String] ; stackspace?RB argscount?RC counter?RD if argscount?RC and 1 stackspace?RB=(argscount?RC+1)*8 else stackspace?RB=argscount?RC*8 end if counter?RD=0 if stackspace?RB sub rsp,stackspace?RB end if if~rdx eq counter?RD=counter?RD+1 if counter?RD<=4 if rdx eqtype 0 size@arg=8 else if rdx eqtype byte 0 virtual at 0 mov[rbx],rdx ; opcode?RE load opcode?RE byte from 0 if opcode?RE and 0F8h=48h size@arg=8 else if opcode?RE=66h size@arg=2 else if opcode?RE=0C7h size@arg=4 else size@arg=1 end if end virtual else virtual at 0 inc rdx ; opcode?RF load opcode?RF byte from 0 if opcode?RF=67h load opcode?RF byte from 1 end if if opcode?RF and 0F8h=48h size@arg=8 else if opcode?RF=66h size@arg=2 else if opcode?RF=0FFh size@arg=4 else size@arg=1 end if end virtual end if if counter?RD=1 if size@arg=8 if~rdx eq rcx mov rcx,rdx end if else if size@arg=4 if~rdx eq ecx mov ecx,rdx end if else if size@arg=2 if~rdx eq cx mov cx,rdx end if else if size@arg=1 if~rdx eq cl mov cl,rdx end if end if else if counter?RD=2 if size@arg=8 if~rdx eq rdx mov rdx,rdx end if else if size@arg=4 if~rdx eq edx mov edx,rdx end if else if size@arg=2 if~rdx eq dx mov dx,rdx end if else if size@arg=1 if~rdx eq dl mov dl,rdx end if end if else if counter?RD=3 if size@arg=8 if~rdx eq r8 mov r8,rdx end if else if size@arg=4 if~rdx eq r8d mov r8d,rdx end if else if size@arg=2 if~rdx eq r8w mov r8w,rdx end if else if size@arg=1 if~rdx eq r8b mov r8b,rdx end if end if else if counter?RD=4 if size@arg=8 if~rdx eq r9 mov r9,rdx end if else if size@arg=4 if~rdx eq r9d mov r9d,rdx end if else if size@arg=2 if~rdx eq r9w mov r9w,rdx end if else if size@arg=1 if~rdx eq r9b mov r9b,rdx end if end if end if else if rdx eqtype[0]|rdx eqtype byte[0] virtual at 0 inc rdx ; opcode?RG load opcode?RG byte from 0 end virtual if opcode?RG and 0F8h=48h mov rax,rdx mov[rsp+(counter?RD-1)*8],rax else if opcode?RG=66h mov ax,rdx mov[rsp+(counter?RD-1)*8],ax else if opcode?RG=0FFh mov eax,rdx mov[rsp+(counter?RD-1)*8],eax else mov al,rdx mov[rsp+(counter?RD-1)*8],al end if else if rdx eqtype 0 mov qword[rsp+(counter?RD-1)*8],rdx else mov[rsp+(counter?RD-1)*8],rdx end if end if end if if~[..arg?R5]eq counter?RD=counter?RD+1 if counter?RD<=4 if[..arg?R5]eqtype 0 size@arg=8 else if[..arg?R5]eqtype byte 0 virtual at 0 mov[rbx],[..arg?R5] ; opcode?RH load opcode?RH byte from 0 if opcode?RH and 0F8h=48h size@arg=8 else if opcode?RH=66h size@arg=2 else if opcode?RH=0C7h size@arg=4 else size@arg=1 end if end virtual else virtual at 0 inc[..arg?R5] ; opcode?RI load opcode?RI byte from 0 if opcode?RI=67h load opcode?RI byte from 1 end if if opcode?RI and 0F8h=48h size@arg=8 else if opcode?RI=66h size@arg=2 else if opcode?RI=0FFh size@arg=4 else size@arg=1 end if end virtual end if if counter?RD=1 if size@arg=8 if~[..arg?R5]eq rcx mov rcx,[..arg?R5] end if else if size@arg=4 if~[..arg?R5]eq ecx mov ecx,[..arg?R5] end if else if size@arg=2 if~[..arg?R5]eq cx mov cx,[..arg?R5] end if else if size@arg=1 if~[..arg?R5]eq cl mov cl,[..arg?R5] end if end if else if counter?RD=2 if size@arg=8 if~[..arg?R5]eq rdx mov rdx,[..arg?R5] end if else if size@arg=4 if~[..arg?R5]eq edx mov edx,[..arg?R5] end if else if size@arg=2 if~[..arg?R5]eq dx mov dx,[..arg?R5] end if else if size@arg=1 if~[..arg?R5]eq dl mov dl,[..arg?R5] end if end if else if counter?RD=3 if size@arg=8 if~[..arg?R5]eq r8 mov r8,[..arg?R5] end if else if size@arg=4 if~[..arg?R5]eq r8d mov r8d,[..arg?R5] end if else if size@arg=2 if~[..arg?R5]eq r8w mov r8w,[..arg?R5] end if else if size@arg=1 if~[..arg?R5]eq r8b mov r8b,[..arg?R5] end if end if else if counter?RD=4 if size@arg=8 if~[..arg?R5]eq r9 mov r9,[..arg?R5] end if else if size@arg=4 if~[..arg?R5]eq r9d mov r9d,[..arg?R5] end if else if size@arg=2 if~[..arg?R5]eq r9w mov r9w,[..arg?R5] end if else if size@arg=1 if~[..arg?R5]eq r9b mov r9b,[..arg?R5] end if end if end if else if[..arg?R5]eqtype[0]|[..arg?R5]eqtype byte[0] virtual at 0 inc[..arg?R5] ; opcode?RJ load opcode?RJ byte from 0 end virtual if opcode?RJ and 0F8h=48h mov rax,[..arg?R5] mov[rsp+(counter?RD-1)*8],rax else if opcode?RJ=66h mov ax,[..arg?R5] mov[rsp+(counter?RD-1)*8],ax else if opcode?RJ=0FFh mov eax,[..arg?R5] mov[rsp+(counter?RD-1)*8],eax else mov al,[..arg?R5] mov[rsp+(counter?RD-1)*8],al end if else if[..arg?R5]eqtype 0 mov qword[rsp+(counter?RD-1)*8],[..arg?R5] else mov[rsp+(counter?RD-1)*8],[..arg?R5] end if end if end if argscount?RC=counter?RD call[lstrcpy] if stackspace?RB add rsp,stackspace?RB end if ;ret ;match any,{retn} ;match,{match epilogue:reglist,epilogue@proc:<regs?R1> ; \{ epilogue Function,flag?R0,parmbytes?R2,localbytes?R3,reglist \}} ;match epilogue:reglist,epiloguedef:<> ;{epilogue Function,flag?R0,parmbytes?R2,localbytes?R3,reglist} ;epiloguedef Function,flag?R0,parmbytes?R2,localbytes?R3,<> ;irps reg,{reverse pop reg} if parmbytes?R2|localbytes?R3 leave end if if flag?R0 and 10000b retn else retn parmbytes?R2 end if ;endp ;purge ret,locals,endl ;finish@proc localbytes?R3=(current?R4+15)and(not 15) end if ;purge finish@proc ;restore regs@proc ;match all,_String{restore all} ;restore _String ;restore args@proc ;match all,TempStr{restore all} ;restore TempStr lstrcpy dq 0 Last edited by LocoDelAssembly on 29 Jun 2009, 15:14; edited 1 time in total |
|||
29 Jun 2009, 15:06 |
|
Tomasz Grysztar 29 Jun 2009, 15:11
It's not so hard to modify the existing one to do it. I leave it as an exercise to the reader (hint: rip a conversion routine from "prepsrc" tool). If anyone makes such an alternative tool, I'll be happy to link it in the fas-tools thread
And using existing tools, you can use prepsrc and the assemble it again and make the listing. Yes, I know that this is an overkill. |
|||
29 Jun 2009, 15:11 |
|
shutdownall 02 Apr 2010, 16:41
I am working now a few weeks with FASM and I am quite happy with it.
Regarding some output listing I have following request. Can you implement an automatic start of output listing when compiling asm project in FASMW.EXE ? I thought about configuring this feature in options first but when I thought about it I would prefer using listing like use16 / use32 / segment statement in sourcecode. So somebody can use this optional in his source code or not. Must be with option -a because in my current project only effective address (through org) is relevant not position in binary file. Even better would be a feature to switch listing on and off for relevant parts if you have a long project. I think adding a functional keyword for this would be helpful for many other users and purposes and maybe is not too much work. I would do myself if anybody can give a hint how to do. I am not willing to analyze the whole project. Thanks, guys. |
|||
02 Apr 2010, 16:41 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.