flat assembler
Message board for the users of flat assembler.

Index > High Level Languages > Need help to convert C code to Fasm

Thread Post new topic Reply to topic

Joined: 22 Dec 2012
Posts: 2
Xerkan 29 Dec 2012, 19:05
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(char* szBuff, int* nBuffSize)
      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: 1178
Location: Unknown
HaHaAnonymous 29 Dec 2012, 20:55
[ Post removed by author. ]

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: 2909
Location: 0x77760000
typedef 30 Dec 2012, 02:21
@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 * pBuff, int * 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        eax, 1

; __stdcall memset
            push ebp
            mov  ebp, esp
                mov     ecx, dword [ebp+16]
                mov     esi, dword [ebp+8]
                mov     eax, dword [ebp+12]
                rep     stosb

        ret 4 * 3

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

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

               push dword[ebp+12] ; str2
               call strlen
                                 ; check for errors here
               mov  ecx, eax
               mov  esi, dword[ebp+12]
               mov  edi, dword[ebp+8]
               rep  movsb
      ret   4 * 2

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

             mov ebx, theLength
             mov eax, dword[ebp+12]  ; pointer on stack
             cmp ebx, dword[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
Tyler 30 Dec 2012, 04:28
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
Xerkan 31 Dec 2012, 12:27
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     esi, eax
    mov     eax, DWORD PTR _nBuffSize$[esp]
     mov     ecx, DWORD PTR [eax]
        cmp     ecx, esi
    jge     SHORT $L180702

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

       mov     edx, DWORD PTR _szBuff$[esp]
        push    ebx
 mov     ebx, ecx
    push    edi
 shr     ecx, 2
      xor     eax, eax
    mov     edi, edx
    rep stosd
   mov     ecx, ebx

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

     mov     eax, esi
    pop     esi

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

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
uart777 06 Jan 2013, 16:39
Useful memory routines:

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

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

function memory.set, p, v, n
push edi
let edi=[p],\
test edi, edi      ; address=0?
jz .e
cmp ecx, 4         ; n<4?
jb @f
push ecx
shr ecx, 2
rep stosd          ; copy dwords
pop ecx
and ecx, 3         ; 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 v, i {  ; (v>>i)&1
let eax=v, ecx=i, eax>>cl, eax&1

macro set.bit v, i {  ; v|=(1<<i)
let eax=1, ecx=i, eax<<cl, v|eax

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

; 1111.0000

macro get.nibble v, i { ; (v>>(i*4))&1111b
let eax=v, ecx=i, ecx<<2, eax>>cl, eax&1111b

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


macro get.couple v, i { ; (v>>(i*2))&11b
let eax=v, ecx=i, ecx<<1, eax>>cl, eax&11b

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

; enable/disable flag

macro enable.f v, n { let eax=n, v|eax }

macro disable.f v, n {
let eax=n
not eax
and v, eax

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

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

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

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

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

function convert.8.32, b
push ebx
let eax=[b],\
ecx=eax, edx=eax, ebx=eax,\
ecx<<8, edx<<16, ebx<<24,\
eax|ecx, eax|edx, eax|ebx
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.2, n
locals i
let eax=[n]
.if eax<2
  jmp .r0
let ecx=eax, ecx-1, eax&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=1, ecx=[i],\
eax<<cl, [i]++
test [n], eax
jnz @b
let eax=[i], eax--
jmp @f
.r0: let 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.n, n, p
let ecx=[p], ecx-1, edx=[n], edx+ecx, eax=ecx,\
eax-edx, eax&ecx, ecx=eax, edx=[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: 192
nmake 06 Mar 2013, 13:59
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
uart777 08 Apr 2013, 14:15
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 *t, t++, 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 a, b

!text.equal $a, $b
if text.case, while *a=*b and *a|*b, a++, b++
else, while IT[*a]=IT[*b] and *a|*b, a++, b++
return (*a|*b)

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

!text.find $t, c
while *t, t++, if *t=c, return 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

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

Website powered by rwasa.