node/lib/metasm/metasm/cpu/ia32/compile_c.rb
def c_prolog
		localspc = @state.offset.values.grep(::Integer).max
		return if @state.func.has_attribute('naked')
		if localspc
			al = typesize[:ptr]
			localspc = (localspc + al - 1) / al * al
			ebp = @state.saved_ebp
			esp = Reg.new(4, ebp.sz)
			instr 'push', ebp
			instr 'mov', ebp, esp
			instr 'sub', esp, Expression[localspc] if localspc > 0

			if @state.func.has_attribute('fastcall')
				if a0 = @state.func.type.args[0]
					instr 'mov', findvar(a0), Reg.new(1, 32)
				end
				if a1 = @state.func.type.args[1]
					instr 'mov', findvar(a1), Reg.new(2, 32)
				end
			else
				@state.func.type.args.each { |a|
					if r = (a.has_attribute_var('register') or a.type.has_attribute_var('register'))
						# XXX if r == ebp, then prepend_prolog mov [esp-off], ebp...
						# XXX this would break when calling anyway (mov ebp, 42; <stuff with &var_42>; call func)
						instr 'mov', findvar(a), Reg.from_str(r)
					end
				}
			end
		end
		@state.dirty -= @state.abi_trashregs	# XXX ABI
		@state.dirty.each { |reg|
			instr 'push', Reg.new(reg, @cpusz)
		}
	end
# holds compiler state information for a function
# registers are saved as register number (see Ia32::Reg)
# TODO cache eflags ? or just z ? (may be defered to asm_optimize)
holds compiler state information for a function
registers are saved as register number
TODO cache eflags . or just z . (may be defered to asm_optimize)
holds compiler state information for a function registers are saved as register number TODO cache eflags . or just z . ( may be defered to asm_optimize )
def c_prolog
		localspc = @state.offset.values.grep(::Integer).max
		return if @state.func.has_attribute('naked')
		if localspc
			al = typesize[:ptr]
			localspc = (localspc + al - 1) / al * al
			ebp = @state.saved_ebp
			esp = Reg.new(4, ebp.sz)
			instr 'push', ebp
			instr 'mov', ebp, esp
			instr 'sub', esp, Expression[localspc] if localspc > 0
			if @state.func.has_attribute('fastcall')
				if a0 = @state.func.type.args[0]
					instr 'mov', findvar(a0), Reg.new(1, 32)
				end
				if a1 = @state.func.type.args[1]
					instr 'mov', findvar(a1), Reg.new(2, 32)
				end
			else
				@state.func.type.args.each { |a|
					if r = (a.has_attribute_var('register') or a.type.has_attribute_var('register'))
						instr 'mov', findvar(a), Reg.from_str(r)
					end
				}
			end
		end
		@state.dirty -= @state.abi_trashregs	
		@state.dirty.each { |reg|
			instr 'push', Reg.new(reg, @cpusz)
		}
	end
def c_prolog localspc = @state . offset . values . grep ( :: Integer ) . max return if @state . func . has_attribute ( 'naked' ) if localspc al = typesize [ :ptr ] localspc = ( localspc + al - 1 ) / al * al ebp = @state . saved_ebp esp = Reg . new ( 4 , ebp . sz ) instr 'push' , ebp instr 'mov' , ebp , esp instr 'sub' , esp , Expression [ localspc ] if localspc > 0 if @state . func . has_attribute ( 'fastcall' ) if a0 = @state . func . type . args [ 0 ] instr 'mov' , findvar ( a0 ) , Reg . new ( 1 , 32 ) end if a1 = @state . func . type . args [ 1 ] instr 'mov' , findvar ( a1 ) , Reg . new ( 2 , 32 ) end else @state . func . type . args . each { | a | if r = ( a . has_attribute_var ( 'register' ) or a . type . has_attribute_var ( 'register' ) ) instr 'mov' , findvar ( a ) , Reg . from_str ( r ) end } end end @state . dirty -= @state . abi_trashregs @state . dirty . each { | reg | instr 'push' , Reg . new ( reg , @cpusz ) } end
holds compiler state information for a function
registers are saved as register number (see Ia32::Reg)
TODO cache eflags ?
holds compiler state information for a function registers are saved as register number ( see Ia32 :: Reg ) TODO cache eflags ?
# XXX if r == ebp, then prepend_prolog mov [esp-off], ebp... # XXX this would break when calling anyway (mov ebp, 42; <stuff with &var_42>; call func) # XXX ABI