Generating x86 assembly with Haskell
A quick and dirty example:
data Exp = Lit Int -- literal value | Call String Exp -- calling a function | Bin BinOp Exp Exp -- binary operations | Param -- the parameter deriving (Show,Eq) data Function = Func String Exp -- a function has a name and expression data BinOp = Add | Subtract | Multiply | Divide deriving(Show,Eq) -- an instance to allow us to write nicer definitions instance Num Exp where x * y = Bin Multiply x y x - y = Bin Subtract x y x + y = Bin Add x y fromInteger x = Lit (fromInteger x) outFunc (Func name it) = name ++ -- output function name ":\npush ebp\nmov ebp,esp\n" ++ -- save old stack frame output it ++ -- output function "pop eax\npop ebp\n" ++ -- restore old stack frame "ret 4\n\n" -- remove argument from stack and return output (Bin op l r) = outBin op l r -- binary operations output (Lit x) = "push dword " ++ show x ++ "\n" -- push literal output (Param) = "push dword [ebp+8]\n" -- push parameter output (Call name with) = output with ++ "call " ++ name ++ "\npush eax\n" -- put return value onto stack outBin Add = outBinGen "add" outBin Subtract = outBinGen "sub" outBin Multiply = outBinGen "imul" outBin Divide = outBinGen "idiv" outBinGen op l r = output l ++ output r ++ "pop ebx\npop eax\n" ++ op ++ " eax,ebx\npush eax\n"
And an example of using it:
main = putStr $ concatMap outFunc [double,quad] double = Func "double" (Param * 2) quad = Func "quad" (Call "double" (2*Param))
This example outputs:
double: push ebp mov ebp,esp push dword [ebp+8] push dword 2 pop ebx pop eax imul eax,ebx push eax pop eax pop ebp ret 4 quad: push ebp mov ebp,esp push dword 2 push dword [ebp+8] pop ebx pop eax imul eax,ebx push eax call double push eax pop eax pop ebp ret 4
Not the most efficient code in the world The calling convention is somewhat ad-hoc; the callee must remove its arguments from the stack and returns its value in
eax.

Hi George – this is a great bit of code!
I’m just starting to get into poking around with compilers, and I’m looking at doing a public-domain compiler for a small FP language. Given that, it’s possible that I may look at using some of this code.
So I was just wondering – is this code basically P.D.? (In other words, “use as you like, but attribution is appreciated”?) If I do use any of it, I’ll certainly give aknowledgement to you!
Looking forward to hearing from you – bye for now!
- Andy
Hi Andy,
You can consider this PD
In general, everything on this blog is under a Creative Commons BY-NC-SA license. I used to have this noted but it seems to have disappeared
Great! Thanks very much, George!
Keep up the good work – this kind of post is really interesting!
Bye for now –
- Andy