How do I pass parameters to a function in Assembly?
I did push Last Param, push Second Param, push First Param..
But I cannot access the parameters within Meh Function.. What I'm doing crashes the program..
format PE console ;Format PE OUT GUI 4.0
entry main
include 'macro/import32.inc'
section '.idata' import data readable ;Import Section.
library msvcrt,'msvcrt.dll'
import msvcrt, printf, 'printf',\
exit,'exit', getchar, 'getchar'
section '.data' data readable writeable ;Constants/Static Section.
InitialValue dd 0
section '.code' code readable executable
main:
push 67
push 66
push 65
call MEH
call [getchar]
mov eax, 0
ret 0
MEH:
push ebx
mov ebp, esp
sub esp, 0
mov eax, [ebp + 8] ; Trying to print first parameter..
push eax
call [printf]
add esp, eax
mov esp, ebp
pop ebx
ret
Small additional notes.
The proper header/footer of the procedure uses push/pop ebp:
MEH:
push ebp
mov ebp, esp
mov esp, ebp
pop ebp
ret
The reason is that we need to save/restore ebp register before using it as a pointer to the arguments and local variables.
Second, CCALL calling convention where the caller restores the stack pointer after procedure return is common for C/C++ language, but not for assembly programming. The reason is obvious - the compiler can properly compute how many parameters are pushed in the stack. In hand written assembly program, using this convention will make the code not legible.
Better approach is to use STDCALL calling convention:
MEH:
push ebp
mov ebp, esp
mov esp, ebp
pop ebp
retn 12 ; how many bytes to be automatically
; removed from the stack after return.
Even better practice is to use some macros in order to automate the creation of the standard procedure elements and to provide human readable labels for the arguments and local variables. For example, macros provided in FreshLib library have following syntax:
proc MEH, .arg1, .arg2, .arg3
; define local variables here, if needed.
begin
; place your code here without headers and footers
return ; will clean the stack automatically.
endp
; pushes the arguments in the stack and call MEH
stdcall MEH, 65, 66, 67
The standard macro library provided with FASM packages has slightly different syntax, that is covered in details by FASM programmers manual.
Let's see...
Say your ESP is 0x00180078 on the outset, then after the three pushes you have
00180078: 67
00180074: 66
00180070: 65
then you call MEH, which immediately pushes ebx so now you have the stack as
00180078: 67
00180074: 66
00180070: 65
0018006C: return address
00180068: ebx value
you now load EBP with ESP = 00180068
sub esp,0 does nothing
mov eax, [ebp+8] ~ 00180068 + 8 = 00180070 = 65
so not the first but rather the last argument
call [printf]
Here comes your problem, though:
add esp, eax
What good was this supposed to do? Assuming printf preserves this argument passed in (which it is incidentally not required to do), why would you add the argument to the stack pointer? That is sure to mess up your return.
What you want to do is restore esp to the value of ebp and pop back the saved ebx value.
If the calling convention for printf() is correct (it is for 32-bit MinGW and 32-bit gcc on Linux), then you're completely ignoring what the function expects and there's no surprise in you not getting the desired output.
The function's prototype is:
int printf(const char* format, ...);
format, the first parameter, is a pointer to an ASCIIZ string, which contains the text to print and/or special tokens like %d to be replaced by the appropriate interpretation of the optional parameters following format.
So, if you want printf() to print 'A', then this is what you need to do in C:
printf("A");
or
printf("%c", 'A');
And here's how you'd do the same in assembly:
myformatstring db "A", 0 ; this line goes into section .data
push myformatstring ; push address of the string
call [printf]
add esp, 4 ; remove all parameters from the stack
or
myformatstring db "%c", 0 ; this line goes into section .data
push 'A'
push myformatstring ; push address of the string
call [printf]
add esp, 2*4 ; remove all parameters from the stack
Related
I am currently getting an "exception thrown" error on the line
mov [ebx], eax
I can't find a solution because all of them use this exact same code and it works for them.
This is an exact copy from my lecture notes and it seems to work for other people except for me.
TITLE Program Template (template.asm)
; Author:
; Last Modified:
; OSU email address:
; Course number/section:
; Project Number: Due Date:
; Description:
INCLUDE Irvine32.inc
.data
intro BYTE "Fun with Arrays! by ", 0
instruction BYTE "This program generates random numbers in the range [100 .. 999], displays the original list, sorts the list, and calculates the median value. Finally, it displays the list sorted in descending order.", 0
request DWORD ?
ask_user BYTE "How many numbers should be generated? [10 ... 200]: ", 0
.code
main PROC
;call randomize
call introduction
push OFFSET request
call getData
exit ; exit to operating system
main ENDP
introduction PROC
mov edx, OFFSET intro
call WriteString
call CrLf
mov edx, OFFSET instruction
call WriteString
call CrLf
introduction ENDP
getData PROC
push ebp
mov ebp, esp
mov edx, OFFSET ask_user
call WriteString
call ReadInt
mov ebx, [ebp+8]
mov [ebx], eax
pop ebp
ret 4
getData ENDP
END main
introduction is missing a ret
Execution falls through from the last instruction of introduction to the first instruction of getData. Execution of machine-code always continues to the next address in memory after the current instruction (unless you use a call/ret/branch); labels and proc declarations are just markers. (Why is no value returned if a function does not explicity use 'ret')
This happens without a valid pointer on the stack. (Because main calls introduction first, without first pushing an address.)
You can look for bugs like this in a debugger by single-stepping your code; the fall-through instead of return to main should catch your attention!
Or use your debugger's backtrace function to see where the call came from: you'll see you reached this line in getData from call introduction, not from call getData.
I'd recommend using a call-clobbered (aka volatile) register for the temporary inside getData. (EAX, ECX, or EDX). ebx is normally call-preserved, so main, and main's caller, expects their EBX value to still be there when the functions return. (But your main doesn't return or use EBX, so there's no actual bug, just a custom calling convention.)
I want to know if there is a way to make a conditional decision and call a function based on that result.
For example. I want to compare something. I want to do the function call if they are even. However, the way I wrote my function I need to call the function and not jump to it. (based on the way my function handles the stack) Is there a way to do that? I have copied my code in as shown, it does not compile.
.endOfForLoop: cmp dword [ebp - 4], 1 ; compares the boolean to one
je call print_prime ; if it is one then prime needs to be printed
jmp call print_not_prime ; otherwise it is not prime
Using NASM, x86 32 bit assembly, linux, intel
Just jump around the function call as if you'd implement an if-then-else:
.endOfForLoop:
cmp dword [ebp-4],1
jne .not_prime
call print_prime
jmp .endif
.not_prime:
call print_not_prime
.endif:
You could also use function pointers and the cmov instruction to make your code branchless, but I advise against writing code like this as it is harder to understand and not actually faster as all branch predictors I know do not try to predict indirect jumps at all.
.endOfForLoop:
cmp dword [ebp-4],1
mov eax,print_prime
mov ebx,print_not_prime
cmovne eax,ebx
call eax
I'm implementing selection sort using assembly code. In the selection sort function, right after I push the registers into the stack, the value of the parameters change
Here's the call in the main, with SIZE =15
array_selection_sort(arrayOfNumbers1, SIZE);
And here's the sort function
void array_selection_sort(int arrayOfIntegers[], int arraySize)
{
__asm{
// BEGIN YOUR CODE HERE
push ebp
mov ebp, esp
push eax
push ebx
push ecx
push edx
push esi
push edi
//assign variables
//ebx = array, ecx = array size - 1, edi = j, edx as temp, esi and edi used for swapping
mov ebx, [ebp + 8]
mov ecx, arraySize
}
The arraySize change from 15 to 2130567168 right after the line
move ebp, esp
Is there anything wrong with my code?
The compiler assumes your parameters are in specific location on stack. When you push to stack, you change the value of the stack pointer and therefore mess with the compiler assumptions.
You don't name the compiler, calling conventions or whatever.
Many questions can be answered by checking the generated assembler, both the calling, and the generated function
does the compiler generate any more code for this function? Maybe it already generates a stackframe.
what kind of instruction does the compiler generate code for mov ecx, arraySize ? register, EBP relative or ESP relative? If it is ESP relative, the compiler thinks it is is a frameless function, even if you generate the frame manually yourself.
Check the calling code how parameters are prepared. You load the array by accessing [ebp+8], so assuming stack conventions, why not load the arraysize by using [ebp+12] ?
I am attempting to learn x86 AT&T syntax and am at a spot where I cam a little confused in general. I understand that there are frames on the stack and when a call is made the first thing that happens in that function is some sort of frame update, then getting parameters. So, if I have some sort of value like 5 in the register eax in my Main area of code and call Function, I still have access to the value 5 in eax correct? Or in order to get it as a parameter I have to do something like this. I saw somewhere else that you pushed your arguments to the stack before calling a function, is this true? I guess something has to be located at 8(ebp) for me to move it into eax, but what is the value of eax before I move something into it with movl? Is it 5? I know this is a lot of questions, I'm just confused at the moment of calling a function and returning something. Any help would be greatly appreciated. I'm sure this is like a piece of cake for some assembly gurus!
Function:
pushl %ebp
movl %esp, %ebp
movl 8(ebp), eax
This page should basically wrap that up.
With cdecl you go like
; I'm not comfortable with AT&T syntax, but it's not relevant here
; void *processData(void *firstParam, void *secondParam)
proc processData
push ebp
mov ebp,esp
mov eax,[dword ptr ss:ebp + 8] ; firstParam
mov edx,[dword ptr ss:ebp + 12] ; secondParam
; do something with the data and put the result into EAX
mov esp,ebp
pop ebp
ret
endp processData
You invoke it like
lea eax,[ds:bufferOfSecondParam]
push eax
lea eax,[ds:bufferOfFirstParam]
push eax
call processData
add esp,8
; Here you can do with the return value anything you want
First of all, you need to decide on the calling convention to use. Win32, for example, uses a variant of cdecl called stdcall where the callee is responsible for cleaning up the stack - this is not too convenient to implement and does not allow for varargs.
[SS:EBP + 8] points to the first argument, because
Arguments are passed onto the stack from right to left ([SS:EBP + 12] points to the second arg)
DWORDS are 4 bytes
[SS:EBP + 0] points to the previous EBP saved upon creation of the stack frame
[SS:EBP + 4] points to the return address reaad into EIP upon ret
I'm currently analyzing a program I wrote in assembly and was thinking about moving some code around in the assembly. I have a procedure which takes one argument, but I'm not sure if it is passed on the stack or a register.
When I open my program in IDA Pro, the first line in the procedure is:
ThreadID= dword ptr -4
If I hover my cursor over the declaration, the following also appears:
ThreadID dd ?
r db 4 dup(?)
which I would assume would point to a stack variable?
When I open the same program in OllyDbg however, at this spot on the stack there is a large value, which would be inconsistent with any parameter that could have been passed, leading me to believe that it is passed in a register.
Can anyone point me in the right direction?
The way arguments are passed to a function depends on the function's calling convention. The default calling convention depends on the language, compiler and architecture.
I can't say anything for sure with the information you provided, however you shouldn't forget that assembly-level debuggers like OllyDbg and disassemblers like IDA often use heuristics to reverse-engineer the program. The best way to study the code generated by the compiler is to instruct it to write assembly listings. Most compilers have an option to do this.
It is a local variable for sure. To check out arguments look for [esp+XXX] values. IDA names those [esp+arg_XXX] automatically.
.text:0100346A sub_100346A proc near ; CODE XREF: sub_100347C+44p
.text:0100346A ; sub_100367A+C6p ...
.text:0100346A
.text:0100346A arg_0 = dword ptr 4
.text:0100346A
.text:0100346A mov eax, [esp+arg_0]
.text:0100346E add dword_1005194, eax
.text:01003474 call sub_1002801
.text:01003474
.text:01003479 retn 4
.text:01003479
.text:01003479 sub_100346A endp
And fastcall convention as was outlined in comment above uses registers to pass arguments. I'd bet on Microsoft or GCC compiler as they are more widely used. So check out ECX and EDX registers first.
Microsoft or GCC [2] __fastcall[3]
convention (aka __msfastcall) passes
the first two arguments (evaluated
left to right) that fit into ECX and
EDX. Remaining arguments are pushed
onto the stack from right to left.
http://en.wikipedia.org/wiki/X86_calling_conventions#fastcall