|
-
November 17th, 2006, 04:42 AM
#1
Returning information from Assembly to C++ without registers
I am in my first semester of assembly on the intel 86x processor, basicly I have been working on this problem for about two weeks and my book and net references haven't been able to help me out.
I am doing a call from C++ into Assembly from this code.
Code:
enum ResultCode {ShowSquare, ShowMultiply, ShowDivide, ShowRemainder, ShowDivideFailure};
enum SuccessCode {Failure, Success};
extern "C" SuccessCode Divide (long, long, long &, long &);
extern "C" void PrintResult (ResultCode, long);
...some code...main....
cout << "Enter mumber to divide into then number to divide by" << endl;
cin >> Num1 >> Num2;
if (Divide (Num1, Num2, Result, Remainder) == Success)
cout << "Result is " << Result << " and remainder is " << Remainder << endl<<endl;
else
cout << "Attempted division by zero" << endl<<endl;
...
void PrintResult (ResultCode PrintCode, long Value)
{
switch (PrintCode)
{
case ShowDivide:
cout << "Display of divide is " << Value << endl;
break;
case ShowRemainder:
cout << "Display of remainder is " << Value << endl;
break;
case ShowDivideFailure:
cout << "Display of Division by zero" << endl;
break;
I have most of the Assembly code up and working but I can't figure out how to modify the result and remainded parameters being passed into the Assembly call after the result and such has been found in my .asm file.
Here is a snippet of my Assembly code
Code:
;_Divide proc dividend:DWORD, divsor:DWORD, result:DWORD, remained:DWORD
_Divide proc
push ebp
mov ebp, esp
; mov eax, dividend
; mov eax, divsor
; mov eax, result
; mov eax, remained
; jmp L2
mov ecx, [ebp + 12] ; num1 dividend
mov eax, [ebp + 8] ; num2 divisor
; cwd
; mov edx, eax
; mov eax, ecx
; cwd
; mov edx, ebx
; mov ecx, eax
; mov eax, ebx
cmp ecx, 0
jne DividFunc
push 0
push 5
call _PrintResult
pop eax
pop eax
mov eax, 0
jmp L2
DividFunc:
sub edx, edx
idiv ecx ; product should be in eax
cmp edx, 0
jne L1
push edx
push eax
push eax
push 2
call _PrintResult
pop eax
pop eax
pop eax
pop edx
; mov dword ptr [ebp+16], eax
; mov dword ptr [ebp+20], edx
; mov ebx, dword ptr [ebp+16]
; mov ecx, dword ptr [ebp+20]
; mov ebx, eax
; mov ecx, edx
mov eax, 1
jmp L2
L1:
push edx
push eax
push 0
push 3
call _PrintResult
pop eax
pop eax
pop eax
pop edx
mov eax, 1
L2:
pop ebp
ret
_Divide endp
My results when I run is;
Code:
Enter mumber to divide into then number to divide by
250
25
Display of divide is 10
Result is 200 and remainder is -858993460
As you can see I've tried a number of different things since what logically I think should work hasn't...I would think that I should be able to reference the position [ebp+16] & [ebp+20] and do a mov into it. Any clarification would be greatly appreciated!
-
December 3rd, 2006, 02:36 AM
#2
Re: Returning information from Assembly to C++ without registers
An important thing to remember is what kind of parameters are being passed on the stack. Are you passing by value or by reference?
Also, you have fallen into a trap of referencing off of ebp. Remember you push ebp in your procedure to preserve it and just before that is your return address (pushed by the call instruction), so the very last parameter pushed onto the stack starts at [ebp+8]
Another note: dividend should be in EAX, divisor in ECX.
Here is a sample program in HLA, it should not be too hard to understand the workings, just remember in HLA, source and destination operands are reversed.
Code:
program divprog;
#includeonce ("stdlib.hhf")
?@nodisplay := true;
?@noalignstack := true;
procedure divide ( dividend:dword; // passed by value
divisor:dword; // passed by value
var res:dword; // passed by reference
var remainder:dword); // passed by reference
@noframe;
begin divide;
push (ebp);
mov (esp, ebp);
mov ([ebp+20], eax); // dividend
mov ([ebp+16], ecx); // divisor
cmp (ecx, 0);
je done;
xor (edx, edx);
idiv (ecx);
// save result into res
mov ([ebp+12], ecx); // address of result
mov (eax, [ecx]);
mov ([ebp+8], ecx); // address of remainder
mov (edx, [ecx]);
done:
pop (ebp);
ret (16); // return balanced stack
end divide;
static
_res :dword;
_rem :dword;
begin divprog;
pushd (7); // dividend
pushd (2); // divisor
pushd (&_res); // address of _res
pushd (&_rem); // address of _rem
call divide;
stdout.put ("result:", _res, " remainder:", _rem, nl);
// output from this program
//result:0000_0003 remainder:0000_0001
end divprog;
Of course, I don't recommend bouncing off EBP. It looks like you are using MASM, so you should be able to use the labels directly from a proc.
Last edited by kahlinor; December 3rd, 2006 at 04:02 AM.
-
December 6th, 2006, 11:10 AM
#3
Re: Returning information from Assembly to C++ without registers
Thank you for the response, I actually managed to figure both of my posts out already but hadn't made it back here yet. Your examples and instructions were very easy to understand, Thank you.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|