_asm function, which prints "Pow (x) = x^2" - c++

I create this piece of code in VS (C++)
#include<iostream>
using namespace std;
static short arr[10];
void powers() {
_asm {
mov ecx, 0;
mov dx, 0;
for:
mov ax, cx;
inc ax;
mul ax;
mov[arr + 2 * ecx], ax;
inc ecx;
cmp ecx, 10;
jl for;
}
}
Now I want to create another function which prints "Pow (x) = x^2", I stuck here:
void print_power(unsigned short x) {
const char* f = "Pow(%d) = %d \n";
_asm {
call powers
push f
add esp, 4
}
}
When I call my "powers" function from "print_power" -> my arr[10] gets filled with the ^2 of 1 to 10
(arr[0] = 1, arr[1] = 4, arr[2] = 9, arr[3] = 16, arr[4] = 25 .....) (I think)
I want when I call my print_power(x) function from main(), for example print_power(8) -> to print the 8th element from my arr like this: "Pow (8) = 81".
Thank you in advance, also I want to apologize if I have some mistakes.

Related

How do you fix error exception for access violation?

I am a little confused as to what I need to fix to handle the error Exception thrown at 0x00AFF748 in ProjectTwo.exe: 0xC0000005: Access violation executing location 0x00AFF748.
I am attempting to write an external assembly language program that is then called by a C++ program. I am unsure if I messed up the assembly language code and that is why I keep getting the error. The goal of my program is
int problem1_ ( )
{
int numberArray [4] = {1, -3, 12, 15};
int result = 0, index = 0;
int numElements = 4;
while (index < numElements)
{
if ( index >= 1 && numberArray[index] > 2 )
{
result = result * numberArray[index] ;
}
else
{
result = result - 5;
}
index++;
}
return result;
}
My C++ Code:
#include<iostream>
using namespace std;
extern "C" int problem1_();
int main()
{
//Declare the variable and set it to returned result
//From calling the assembly program
int x = problem1_();
//Print the results
cout << "The result is: "<< x << endl;
return 0;
}
My assembly Language code:
.model flat, c
.data
numberArray DWORD 1, -3, 12, 15
numElements DWORD 5
.code
problem1_ proc
mov eax, 0 ;value of eax is 0
lea ebx, numberArray ;Load the array's memory address into register ebx'
mov ecx, numElements ;ecx is count down counter
cmp ecx, 0 ;If ecx not greater than 0, jump to quit
jng FINISH
iterateThruArray:
cmp[ebx], eax ;Compare value at current index to eax
jl result1
jmp result2
result1:
mul numberArray
jmp FINISH
result2:
sub eax, 5
jmp FINISH
FINISH:
pop ebp ; pop ebp from the stack
ret ; return to calling program
problem1_ endp
end

Inline assembly, error: operand size conflict

I'm trying to write some simple asm code for practice but I get this error: error C2443: operand size conflict
I only want to add 2 numbers and then move the result to another variable.
#include<stdio.h>
int main() {
int a = 3, b = 3, c;
__asm {
mov ax, a;
mov bx, b;
add ax, bx;
mov c, ax;
}
printf("%d", c);
}

Optimize a algorithm that find a specific Fibonacci number

Given an number A, I want to find the Ath Fibonacci number
that is multiple of 3 or if the number representation has at least a 3
on it.
Example:
Fibonacci > 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, ...
Input: 1, Output: 3;
3 is the first Fibonacci number that is multiple of 3 or has an 3 on
it.
Input: 3, Output: 21;
21 is the third Fibonacci number that is multiple of 3 or has an 3 on
it.
Edit: Variable type changed to unsigned long long int and ajust on Fibonacci generator. Thanks #rcgldr and #Jarod42 for the help!
My code:
#include<bits/stdc++.h>
using namespace std;
int tem(unsigned long long int i){
while(i != 0){
if(i%10 == 3){
return true;
}
i = i/10;
}
return false;
}
int main(){
int a, count = 0;
unsigned long long int f1 = 1, f2 = 1;
while(scanf("%d", &a) != EOF){
for(unsigned long long int i = 2; i > 0; i++){
i = f1 + f2;
f1 = f2;
f2 = i;
if((i%3 == 0) || tem(i)){
count++;
if(count == a){
cout << i << endl;
break;
}
}
}
}
}
When A > 20, it starts to slow down. Makes sense because it tends to be exponecial. My code is not very efficient, but I didn't find an better logic to use.
I looked into these links, but didn't find an conclusion:
1 - Recursive Fibonacci
2 - Fibonacci Optimization
Any ideas? Thanks for the help!
You can speed up the Fibonacci part using this sequence
uint64_t f0 = 0; // fib( 0)
uint64_t f1 = 1; // fib(-1)
int n = ... ; // generate fib(n)
for(int i = 0; i < n; i++){
std::swap(f0,f1);
f0 += f1;
}
Note Fib(93) is the maximum Fibonacci number that fits in a 64 bit unsigned integer, it also has a 3 in it. Fib(92) is the maximum Fibonacci number that is a multiple of 3.
I used this example code to find all of the values (a ranges from 0 to 62), it seems to run fairly fast, so I'm not sure what the issue is. Is optimization enabled?
#include <iostream>
#include <iomanip>
typedef unsigned long long uint64_t;
int tem(uint64_t i){
while(i != 0){
if(i%10 == 3)
return true;
i = i/10;
}
return false;
}
int main(){
int a = 0, n;
uint64_t f0 = 1, f1 = -1; // fib(-1), fib(-2)
for(n = 0; n <= 93; n++){
std::swap(f0, f1); // f0 = next fib
f0 += f1;
if((n&3) == 0 || tem(f0)){
std::cout << std::setw( 2) << a << " "
<< std::setw( 2) << n << " "
<< std::setw(20) << f0 << std::endl;
a++;
}
}
return 0;
}
Depending on the compiler, i%10 and i/10 may use a multiply by "magic number" and shift to replace divide by a constant. Code generated by Visual Studio 2015 for tem(), which is fairly "clever":
tem proc ;rcx = input
test rcx,rcx ; return false if rcx == 0
je SHORT tem1
mov r8, 0cccccccccccccccdh ;magic number for divide by 10
tem0: mov rax, r8 ;rax = magic number
mul rcx ;rdx = quotient << 3
shr rdx, 3 ;rdx = quotient
lea rax, QWORD PTR [rdx+rdx*4] ;rax = quotient*5
add rax, rax ;rax = quotient*10
sub rcx, rax ;rcx -= quotient * 10 == rcx % 10
cmp rcx, 3 ;br if rcx % 10 == 3
je SHORT tem2
mov rcx, rdx ;rcx = quotient (rcx /= 10)
test rdx, rdx ;loop if quotient != 0
jne SHORT tem0
tem1: xor eax, eax ;return false
ret 0
tem2: mov eax, 1 ;return true
ret 0
tem endp
Just pointing out some obvious coding errors
for(unsigned long long int i = 2; i > 0; i++)
is redundant.
for(;;){
unsigned long long i = f1+f2;
should suffice. Secondly
return 0;
is meaningless because it breaks out of the while loop. A break would be better.
There's a clever way to do Fibonacci.
http://stsievert.com/blog/2015/01/31/the-mysterious-eigenvalue/
Code's in python and is just for the nth number, but I think you get the idea.
def fib(n):
lambda1 = (1 + sqrt(5))/2
lambda2 = (1 - sqrt(5))/2
return (lambda1**n - lambda2**n) / sqrt(5)
def fib_approx(n)
# for practical range, percent error < 10^-6
return 1.618034**n / sqrt(5)

Working on Array inside Struct , with Assembly

Im trying to check the even numbers from an array inside a struct, but i dont think i wrote something right. When debugging, (i.e. count = 3 v[] = {1,2,4}), after it reaches " cmp eax,[ebp+12] and je outt; " , it goes to outt: and thats it.
s is supposed to keep the sum of all even numbers, eax inside int suma(test *) is index for array, and edx keeps the sum before moving it in s
what am i doing wrong?
#include "stdafx.h"
#include <iostream>
using namespace std;
struct test {
int v[10];
short count;
};
test a;
int s = 6;
int suma(test *)
{
_asm {
mov eax, 0; // i for counting inside array
mov edx, 0; // sum of even elements
mov ebx, [ebp + 8]; // array v adress
loop:
cmp eax, [ebp + 12];
je outt;
mov ecx, [ebx + 4 * eax];
inc eax;
mov edi, ecx
and ecx, 1;
cmp ecx, 1;
je loop;
add edx, edi;
jmp loop;
outt:
mov eax, edx;
}
return s;
}
int main()
{
cin >> a.count;
for (int i = 0; i < a.count; i++)
cin >> a.v[i];
_asm {
LEA eax, a
push eax;
call suma;
add esp, 4;
mov s, eax;
}
cout << s;
return 0;
}

C++ inline assembly function not working properly

I get a different return value each time, so I'm doing something wrong. If I replace the add with a basic inc, it returns correctly.
Here is the code.
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <iostream>
using namespace std;
int Add ( int _Number1, int _Number2 );
int main ( int _ArgumentCount, char * _Arguments[] )
{
int nInput, nOutput;
nOutput = Add ( 1, 1 );
cout << "1 + 1 = " << nOutput << endl;
cin >> nInput;
return 0;
}
__declspec ( naked ) int Add ( int _Number1, int _Number2 )
{
__asm xor eax, eax
__asm mov eax, _Number1
__asm add eax, _Number2
__asm ret
}
Here is the new, working code:
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <iostream>
using namespace std;
int Add ( int Number1, int Number2 );
int main ( int ArgumentCount, char * Arguments[] )
{
int nInput, nOutput;
nOutput = Add ( 1, 1 );
cout << "1 + 1 = " << nOutput << endl;
cin >> nInput;
return 0;
}
int Add ( int Number1, int Number2 )
{
__asm mov eax, Number1
__asm add eax, Number2
}
__declspec (naked) means the function is created without any prolog or epilog code -- so if you want to access formal parameters, you need to write prolog code of your own to give you access to them. Your xor is also accomplish nothing, since you immediately overwrite eax with another value. Also note that any identifier starting with an underscore followed by a capital letter is reserved, so your code had undefined behavior. Try rewriting your function as:
int Add ( int number1, int number2 )
{
__asm mov eax, number1
__asm add eax, number2
}
or else write the code to access the parameters on the stack without depending on a prolog:
__declspec (naked) int Add2(int number1, int number2) {
_asm mov eax, [esp+4]
_asm add eax, [esp+8]
_asm ret
}
I didn't check, but I'd guess your original code was trying to load the parameters from [ebp+8] and [ebp+12]. This depends on the normal prolog code:
push ebp
mov ebp, esp
...which your __declspec (naked) specifically told the compiler not to generate.