flat assembler
Message board for the users of flat assembler.
 Home   FAQ   Search   Register 
 Profile   Log in to check your private messages   Log in 
flat assembler > High Level Languages > Need help to convert C code to Fasm

Thread Post new topic Reply to topic

Joined: 22 Dec 2012
Posts: 2

Need help to convert C code to Fasm

i am new to Fasm ,i found it very useful for creating small DLLs
i have managed to build a simple dll with few functions
but i need help for further steps
i am not going to use it to create complex applications , as it is very hard for me to understand Assembly syntax
i am only going to use it to make wrapper dlls to Windows API functions

i need help with the following function , as you can see that the arguments are pointers to data in caller's state
and this is a two-pass function , first time caller will get the required size of memory and allocate it then second time callee will copy szText to allocated memory

char szText[] = "Hello World";

int GetText(charszBuffintnBuffSize)
      int nTextLength = strlen(szText);
   if(*nBuffSize < nTextLength)
              *nBuffSize = nTextLength;
           return -1;
  } else
              return nTextLength;

can you please show me how to convert this function to a dll procedure in Fasm

PS: szText variable can also be defined as local variable of GetText()

Post 29 Dec 2012, 19:05
View user's profile Send private message Reply with quote

Joined: 02 Dec 2012
Posts: 1171
Location: Unknown

Stupid post removed.

Last edited by HaHaAnonymous on 28 Feb 2015, 22:08; edited 1 time in total
Post 29 Dec 2012, 20:55
View user's profile Send private message Reply with quote

Joined: 25 Jul 2010
Posts: 2910
Location: 0x77760000

@op Untested. Find any bugs and learn from it.

If calling from C/C++ define the function prototype first as __stdcall.


HMODULE hLib =LoadLibrary("fasm_code.dll");
typedef int (__stdcall *GetText)(char * pBuffint * cbSize) = (int (__stdcall*)(char*,int*) ) GetProcAddress(hLib,"GetText");
int length = 12356;
char * myBuffer = (char*)malloc(length);

length = GetText(myBuffer, &length);


format pe gui 4.0 dll

include 'win32a.inc'

entry DllMain

section '.code' code readable executable

proc DllMain
     mov        eax1

; __stdcall memset
            push ebp
            mov  ebpesp
                mov     ecxdword [ebp+16]
                mov     esidword [ebp+8]
                mov     eaxdword [ebp+12]
                rep     stosb

        ret 4 * 3

; __stdcall strlen
      strlen:; (str)
             push ebp
             mov  ebpesp
                mov al,  0    ; Scan for null byte
                mov eax, -1   ; Make the loop infinite until we hit the null byte
                mov edidword[ebp+8]
                repne scasb
                mov eax, -2   ; If first byte is null ECX will be -2
                sub eaxecx
      ret 4

; __stdcall strcpy. Quick and dirty. Not good for production
            push ebp
            mov  ebpesp

               push dword[ebp+12; str2
               call strlen
                                 ; check for errors here
               mov  ecxeax
               mov  esidword[ebp+12]
               mov  edidword[ebp+8]
               rep  movsb
      ret   4 * 2

; __stdcall GetText (pBuff, length)
             push ebp
             mov  ebpesp
             push ebx

             mov ebxtheLength
             mov eaxdword[ebp+12]  ; pointer on stack
             cmp ebxdword[eax]     ; what's on that pointer
             jg  @Z

             push   dword[eax]
             push   0
             push   dword[ebp+8]
             call   memset           ; can also be transformed into a macro

             push   theString
             push   dword[ebp+8]
             call   strcpy
             mov    ebx,  eax
             pop ebx
        ret  4 * 2

section '.data' data readable writeable

theString   db 'Rush Rush Rush !. Oh no!',0
theLength   = $ - theString

section '.export' export data readable

export 'stringz.dll',\

section '.reloc' data fixups discardable

Post 30 Dec 2012, 02:21
View user's profile Send private message Reply with quote

Joined: 19 Nov 2009
Posts: 1216
Location: NC, USA

If all you want is to convert C to asm, you can do that (sorta) with GCC, using gcc -S -masm=intel "source.c". It will be in Intel syntax but a little different from Fasm's Intel syntax, so it'll take just a little editing. Also, you'll probably want to use -O3, unless you want your code to be 1000 lines for absolutely no reason.
Post 30 Dec 2012, 04:28
View user's profile Send private message Reply with quote

Joined: 22 Dec 2012
Posts: 2

sorry for late reply

yes we usually use the CRT functions in C Smile


thank you very much for the example you showed
i tried it ( with __stdcall) but it crashes at the point where memset
i am a Visual Studio user and usually use .def file to export a function from a dll
which means __cdecl calling convention

i can not modify the host application that loads this DLL and i have to export functions as __cdecl 'ed

yes i want to convert C code to Assembly that i can compile with Fasm
actually, my first attempt was the modifying a Assembly output of this function (and others) generated by Visual Studio
but i could not get it to work as well

this is the exact Asm output of visual studio which works well when compiled with Visual Studio

PUBLIC   ?GetText@@YAHPADPAH@Z           ; GetText
; Function compile flags: /Ogty
_szBuff$ = 8                                         ; size = 4
_nBuffSize$ = 12                                  ; size = 4
?GetText@@YAHPADPAH@Z PROC NEAR           ; GetText, COMDAT
   push    esi
 push    OFFSET FLAT:?szText@@3PADA  ; szText
    call    DWORD PTR __imp__lstrlenA@4
 mov     esieax
    mov     eaxDWORD PTR _nBuffSize$[esp]
     mov     ecxDWORD PTR [eax]
        cmp     ecxesi
    jge     SHORT $L180702

  mov     DWORD PTR [eax], esi
        or      eax, -1
     pop     esi
 ret     0

       mov     edxDWORD PTR _szBuff$[esp]
        push    ebx
 mov     ebxecx
    push    edi
 shr     ecx2
      xor     eaxeax
    mov     ediedx
    rep stosd
   mov     ecxebx

        push    OFFSET FLAT:?szText@@3PADA  ; szText
    and     ecx3
      push    edx
 rep stosb
   call    DWORD PTR __imp__lstrcpyA@8
 pop     edi
 pop     ebx

     mov     eaxesi
    pop     esi

 ret     0
?GetText@@YAHPADPAH@Z ENDP                 ; GetText

note: i forwarded __imp__lstrcpyA and __imp__lstrlenA@4 to msvcrt.dll with import on my tests
and did modifications acorrding the Fasm's error descriptions

can you guys help me to convert this Masm code to Fasm

Thanks for your help
Post 31 Dec 2012, 12:27
View user's profile Send private message Reply with quote

Joined: 17 Jan 2012
Posts: 369

Useful memory routines:

;;;;;;;;;;;;;;;; MEMORY COPY, SET ;;;;;;;;;;;;;;;;

function memory.copyabn
push esi edi
let edi=[a],\
 esi=[b], ecx=[n]
test ediesi      ; address=0?
jz .e
cmp ecx4         ; if n<4
jb @f
push ecx
shr ecx2         ; n/4
rep movsd          ; copy dwords
pop ecx
and ecx3         ; modulo 4
jz .e              ; remainder?
rep movsb          ; copy bytes
pop edi esi

function memory.setpvn
push edi
let edi=[p],\
test ediedi      ; address=0?
jz .e
cmp ecx4         ; n<4?
jb @f
push ecx
shr ecx2
rep stosd          ; copy dwords
pop ecx
and ecx3         ; modulo 4
jz .e              ; remainder?
rep stosb          ; copy bytes
pop edi

;;;;;;;;;;;;;;;; GET/SET/ZERO BIT ;;;;;;;;;;;;;;;;

; 76543210. warning: eax/ecx/edx cannot be used
; as parameters. 'v' should be m, 'i' can be mi

macro get.bit vi {  ; (v>>i)&1
let eax=vecx=ieax>>cleax&1

macro set.bit vi {  ; v|=(1<<i)
let eax=1ecx=ieax<<clv|eax

macro zero.bit vi { ; v&=~(1<<i)
let eax=1ecx=ieax<<cl
not eax
and veax

; 1111.0000

macro get.nibble vi { ; (v>>(i*4))&1111b
let eax=vecx=iecx<<2eax>>cleax&1111b

macro set.nibble vin { ; v|=(n<<(i*4))
let eax=vecx=iedx=necx<<2edx<<cl,\


macro get.couple vi { ; (v>>(i*2))&11b
let eax=vecx=iecx<<1eax>>cleax&11b

macro set.couple vin { ; v|=(n<<(i*2))
let eax=vecx=iedx=necx<<1edx<<cl,\

; enable/disable flag

macro enable.f vn { let eax=nv|eax }

macro disable.f vn {
let eax=n
not eax
and veax

macro toggle n { xor n1 } ; invert 1/0

; create AA.BBB.CCCb/AA.BB.CC.DDb BIT structures

function tripletabc
let eax=[a], eax<<6,\
ecx=[b], ecx<<3eax|ecxeax|[c]

function quadrupletabcd
let eax=[a], eax<<6ecx=[b], ecx<<4,\
edx=[c], edx<<2eax|ecxeax|edxeax|[d]

; expand byte AAh to AA.AA.AA.AAh

function convert.8.32b
push ebx
let eax=[b],\
pop ebx

;;;;;;;;;;;;;;;;;; POWERS OF 2 ;;;;;;;;;;;;;;;;;;;

; an unsigned number is a power of 2 if only
; 1 BIT is set: if !(n&n-1). subtracting 1
; inverts all BITs. if n=10000000b (80h/128),
; n&01111111b=0

; to find out which power of 2, search n
; for 1st 0 BIT from right to left

; is n power of 2? example: power.2 128
; returns 7

function power.2n
locals i
let eax=[n]
.if eax<2
  jmp .r0
let ecx=eaxecx-1eax&ecx
.if eax
  jmp .r0 ; not power of 2

; which power of 2?
; n--
; loop i=1, n&1<<i, i++

let [n]--, [i]=1
let eax=1ecx=[i],\
eax<<cl, [i]++
test [n], eax
jnz @b
let eax=[i], eax--
jmp @f
.r0let eax=0

;;;;;;;;;;;;;;;;;;;;; ALIGN ;;;;;;;;;;;;;;;;;;;;;;

; versatile align n/umber by power of 2

; return n aligned to p in eax. in ecx,
; return the quantity to add to make n
; divisible by p. algorithm:

; n+(((p-1)-(n+p-1))&(p-1))

function align.nnp
let ecx=[p], ecx-1edx=[n], edx+ecxeax=ecx,\
eax-edxeax&ecxecx=eaxedx=[n], eax+edx

Ultimate HL features: http://board.flatassembler.net/topic.php?t=14768
Post 06 Jan 2013, 16:39
View user's profile Send private message Reply with quote

Joined: 13 Sep 2012
Posts: 193

uart777, I am being friendly, but I recall you accused someone on the forum for being a HLL programmer and a lover of windows 8, and that he was not a real asm programmer. But now I see you embrace your own type of HLL implementation in assembly. Do you like HLL or not? Smile

If people wanted to use HLL, would they come to an assembly forum..

1. People ran away from assembly, because they needed HLL.

2. Then people came back to assembly, just to re-invent HLL.

Very Happy
Post 06 Mar 2013, 13:59
View user's profile Send private message Reply with quote

Joined: 17 Jan 2012
Posts: 369

Do you like HLL or not?

Z77 is a low-level language, a compact symbol-based version of machine code. I refer to it as HL because most programmers here only understand things in black/white, they do not understand the precise differences between LL/HL code and that is a variable percentage. HLLs can be improved dramatically. My "language":

!text.n $t
byte *p=t
while *tt++, then return t-p

!text.copy $a$b
while *b, *a++=*b++, then *a=0

!text.attach $a$b
a+=text.n(a), text.copy ab

!text.equal $a$b
if text.casewhile *a=*b and *a|*ba++, b++
elsewhile IT[*a]=IT[*band *a|*ba++, b++
return (*a|*b)

!text.compare $a$b
while *a=*b and *a|*ba++, b++, then return *a-*b

!text.find $tc
while *tt++, if *t=creturn t
return 0

Post 08 Apr 2013, 14:15
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

Main index   Download   Documentation   Examples   Message board
Copyright © 2004-2018, Tomasz Grysztar.
Powered by rwasa.