I've got some code (simply powers) which I'm inlining in assembly because I have nothing else to do right now. I can't, however, get the result to be returned or printed to the console. Can anyone help?
#include <iostream.h>
void power2(int num, int power, unsigned int outl)
{
__asm
{
mov eax, num
mov ecx, power
mov ebx, outl
shl eax, cl
out eax, outl
}
}
int main()
{
power2(5, 3, (unsigned int) sizeof(cout));
return 0;
}
Out is for device IO. You need to call printf (or equivalent) from your assembly code, or just return the value and printf it in main (that would be better).
Quote from: rabbit on March 10, 2005, 10:36 AM
I've got some code (simply powers) which I'm inlining in assembly because I have nothing else to do right now. I can't, however, get the result to be returned or printed to the console. Can anyone help?
#include <iostream.h>
void power2(int num, int power, unsigned int outl)
{
__asm
{
mov eax, num
mov ecx, power
mov ebx, outl
shl eax, cl
out eax, outl
}
}
int main()
{
power2(5, 3, (unsigned int) sizeof(cout));
return 0;
}
I like the novel idea of getting the size of cout and using that as the output port to send the data to. Must've required some creative thinking :)
Quote from: Adron on March 10, 2005, 12:56 PM
I like the novel idea of getting the size of cout and using that as the output port to send the data to. Must've required some creative thinking :)
Heh I noticed that too. I was wondering how that was supposed to work. :P
#include <cstdio>
unsigned int power2(int num, int power)
{
__asm
{
mov eax, num
mov ecx, power
shl eax, cl
}
// return value is in eax already
}
int main()
{
std::printf("%d\r\n", power2(x, y));
return 0;
}
Thanks, K, that work's after some modification :)
I used sizeof(cout) because I knew out couldn't take an ostream as a parameter, but it didn't work ><
The sizeof operator returns the size in bytes of its operand (or the length of the array if the operand is an array). Why would that be a valid device handle? It would just be the number of bytes an instance of class ostream occupies.
Think about what you're doing. :P
I needed to make it a number somehow :P
Quote from: Zakath on March 12, 2005, 05:08 PM
The sizeof operator returns the size in bytes of its operand (or the length of the array if the operand is an array).
So given this:
int x[10];
cout << sizeof(x) << endl;
, it should print 10? ;) The length of the array is 10, but that's not its size...
Quote from: rabbit on March 12, 2005, 07:08 PM
I needed to make it a number somehow :P
Perhaps you could've taken the address of an object of type cout?
I don't know that much C++!
Quote from: rabbit on March 13, 2005, 08:15 AM
I don't know that much C++!
If you don't know how to use pointers, you shouldn't be using C++ *or* assembly.
I know pointers, just not too well. I'm still learning, remember. And ACTUALLY, I learned Assembly first, during my electronics course.
Quote from: Kp on March 12, 2005, 08:30 PM
Quote from: Zakath on March 12, 2005, 05:08 PM
The sizeof operator returns the size in bytes of its operand (or the length of the array if the operand is an array).
So given this:int x[10];
cout << sizeof(x) << endl;
, it should print 10? ;) The length of the array is 10, but that's not its size...
My mistake. I was going from memory, and it appears that my memory has a leak in it.
It returns the total number of bytes occupied by the array, not the length of the array.
I was just curious though, why are you using inline assembler to create a power evaluation function? Why not just use plain C++...
unsigned long EvaluatePower(unsigned long base, unsigned long exponent)
{
if(exponent == 0)
return 1;
else if(exponent == 1)
return base;
else {
unsigned long value = 0;
unsigned long tracker = base;
for(unsigned int i = 1; i < exponent; i++) {
value = base * tracker;
tracker = value;
}
return value;
}
}
Note: Does not support negative exponents. If you want this supported you'll have to change the values to type signed and come up with some thinking as to how to process a negative exponent (e.g. taking the recipricol of the evaluated power).
Quote from: Mephisto on March 14, 2005, 08:56 AM
I was just curious though, why are you using inline assembler to create a power evaluation function? Why not just use plain C++...
unsigned long EvaluatePower(unsigned long base, unsigned long exponent)
{
if(exponent == 0)
return 1;
else if(exponent == 1)
return base;
else {
unsigned long value = 0;
unsigned long tracker = base;
for(unsigned int i = 1; i < exponent; i++) {
value = base * tracker;
tracker = value;
}
return value;
}
}
Note: Does not support negative exponents. If you want this supported you'll have to change the values to type signed and come up with some thinking as to how to process a negative exponent (e.g. taking the recipricol of the evaluated power).
Well, that loop will be much slower than his power2 function for calculating numbers times powers of two. It would be much easier to just define it:
unsigned int power2(int num, int power)
{
return num << power;
}
That is, if you at all bother to make it a subroutine :)
For a generic exponentiation function, you'd probably want to use floating point math and the built-in functions, since you'll run out of number range quickly when exponentiating ints.
I could switch over to unsigned double if I need to, but I don't.
The only reason I was doing this in assembly in the first place was to prove that I could prove to my friend that it's possible to write assembly code in MSVC++. The only part I didn't quite understand was the return, but that's because the assembly I learned with output to some LED's, not a console.
On top of that, I like assembly :)
Quote from: Adron on March 14, 2005, 05:11 PM
Quote from: Mephisto on March 14, 2005, 08:56 AM
I was just curious though, why are you using inline assembler to create a power evaluation function? Why not just use plain C++...
unsigned long EvaluatePower(unsigned long base, unsigned long exponent)
{
if(exponent == 0)
return 1;
else if(exponent == 1)
return base;
else {
unsigned long value = 0;
unsigned long tracker = base;
for(unsigned int i = 1; i < exponent; i++) {
value = base * tracker;
tracker = value;
}
return value;
}
}
Note: Does not support negative exponents. If you want this supported you'll have to change the values to type signed and come up with some thinking as to how to process a negative exponent (e.g. taking the recipricol of the evaluated power).
Well, that loop will be much slower than his power2 function for calculating numbers times powers of two. It would be much easier to just define it:
unsigned int power2(int num, int power)
{
return num << power;
}
That is, if you at all bother to make it a subroutine :)
For a generic exponentiation function, you'd probably want to use floating point math and the built-in functions, since you'll run out of number range quickly when exponentiating ints.
Off hand, I don't think base << exponent would calculate the power. Not sure what you meant by if you bother making it a subroutine. :p
Quote from: Mephisto on March 14, 2005, 05:43 PM
Quote from: Adron on March 14, 2005, 05:11 PM
Well, that loop will be much slower than his power2 function for calculating numbers times powers of two. It would be much easier to just define it:
unsigned int power2(int num, int power)
{
return num << power;
}
That is, if you at all bother to make it a subroutine :)
For a generic exponentiation function, you'd probably want to use floating point math and the built-in functions, since you'll run out of number range quickly when exponentiating ints.
Off hand, I don't think base << exponent would calculate the power. Not sure what you meant by if you bother making it a subroutine. :p
The routine this thread is about doesn't calculate powers though. His power2 routine calculates num * 2**power. If he were to use your routine to calculate num * 2**power, he'd be doing
#define power2(num, power) ((num)*EvaluatePower(2, power))
At least to me it's rather obvious that that's much slower than just shifting the number, and most people don't make a subroutine for shifting a number since there's a shifting operator available :)
Quote from: Adron on March 14, 2005, 06:10 PM
Quote from: Mephisto on March 14, 2005, 05:43 PM
Quote from: Adron on March 14, 2005, 05:11 PM
Well, that loop will be much slower than his power2 function for calculating numbers times powers of two. It would be much easier to just define it:
unsigned int power2(int num, int power)
{
return num << power;
}
That is, if you at all bother to make it a subroutine :)
For a generic exponentiation function, you'd probably want to use floating point math and the built-in functions, since you'll run out of number range quickly when exponentiating ints.
Off hand, I don't think base << exponent would calculate the power. Not sure what you meant by if you bother making it a subroutine. :p
The routine this thread is about doesn't calculate powers though. His power2 routine calculates num * 2**power. If he were to use your routine to calculate num * 2**power, he'd be doing
#define power2(num, power) ((num)*EvaluatePower(2, power))
At least to me it's rather obvious that that's much slower than just shifting the number, and most people don't make a subroutine for shifting a number since there's a shifting operator available :)
Oh, I didn't even realize what his function was doing. I just assumed by the name of it he was trying to calculate power expressions generically. My bad.