I have a problem, I have to use C++ and ASM to make a program, here is the description:
I have to make a program in C++ that creates a Linked List of doubles and then in ASM using the list just add every number on it and return the result. That's all.

I have the C++ part, I just don't know how to advance through the linked list, that's my problem, I know how to use the FPU that's np . It could be C also so no prblem with that. I use NASM syntax, cause I use NASM.

The ASM prototype should be: addDoubles(List l, int listSize);

and here is the C++ part, just the important:

class node {

void* info; //info could be int, double, char, etc.
node* next;

public:
node (void* v) {
info =v;
next=0;
}
void poner_next (node*n){
next = n;
}
node* read_next(){
return next;
}
void* read_info(){
return info;
}
};

class list{
node* header;
int node_num;

public:
list(){
node_num = 0;
header = 0;
}
void remove(int);
void insert (void*, int);
void put (void* v){
insertar (v, node_num+1);
}
void* find(int);
void print();
};


Thanks
Posted on 2002-12-06 17:30:00 by KarmaPolice
sample code:
[size=9]#include <iostream>


using std::cout;
using std::endl;

class list
{
private:
protected:
public:
double num;
list* next;
};

class doublell
{
private:
list *rootnode;
list *prevnode;
void init(void)
{
rootnode = NULL;
prevnode = NULL;
}
void addnode(double value)
{
if(!rootnode)
{
rootnode = new list;
rootnode->next = NULL;
rootnode->num = value;
prevnode = rootnode;
}
else
{
prevnode->next = new list;
prevnode->next->next = NULL;
prevnode->next->num = value;
prevnode = prevnode->next;
}
}
void printnodes(list *node)
{
while(node)
{
cout<<node->num<<endl;
node = node->next;
}
}
void destroylist(list *node)
{
list *deallocatethisnode;
while(node)
{
deallocatethisnode = node;
node = node->next;
delete deallocatethisnode;
}
}
[color=blue]void asmtraverse(list *node)
{
double value;

cout<<endl<<endl;

//Get the value of the first node

__asm
{
mov edx, node
mov eax, DWORD PTR [edx]
mov DWORD PTR [value], eax
mov eax, DWORD PTR [edx+4]
mov DWORD PTR [value+4], eax
}

cout<<"First Node Has A Value Of "<<value<<endl;

//Traverse to the next node

__asm
{
mov edx, node
mov eax, DWORD PTR [edx+8]
mov node, eax
}

//Get the value of the second node

__asm
{
mov edx, node
mov eax, DWORD PTR [edx]
mov DWORD PTR [value], eax
mov eax, DWORD PTR [edx+4]
mov DWORD PTR [value+4], eax
}

cout<<"Second Node Has A Value Of "<<value<<endl;

//Traverse to the next node

__asm
{
mov edx, node
mov eax, DWORD PTR [edx+8]
mov node, eax
}

//Get the value of the third node

__asm
{
mov edx, node
mov eax, DWORD PTR [edx]
mov DWORD PTR [value], eax
mov eax, DWORD PTR [edx+4]
mov DWORD PTR [value+4], eax
}

cout<<"Third Node Has A Value Of "<<value<<endl<<endl;;
}[/color]
protected:
public:
doublell(void)
{
init();
addnode(1);
addnode(5);
addnode(4);
printnodes(rootnode);
asmtraverse(rootnode);
}
~doublell(void)
{
destroylist(rootnode);
};
};

int main(void)
{
doublell start;
return 0;
}[/size]
First thing to remember here are the sizes of your classes and variables.

A pointer here holds a 32 bit value or DWORD size.

Our class (list) holds a double and a dword size variable, so this class is 12 bytes total.

I don't know how to use NASM but I'm sure you'll get the idea on how to traverse the LL.

This code is the heart of how we will traverse the LL.
__asm

{
mov edx, node
mov eax, DWORD PTR [edx+8]
mov node, eax
}
First you get a pointer to a node. This is the basis of your starting point.

Remember the order of you variables on your class matters. Since we have a double variable before our next node pointer and since a double is 8 bytes, we advance 8 bytes further into the class. Then we retrieve the pointer.

That's it, that's the key on traversing a LL in ASM.

This code was tested using MS-VC 6.

:)
Posted on 2002-12-06 19:09:58 by stryker
There are no error checkings in the code. And the function asmtraverse is static, so I'll just leave it to you to make it "dynamic" (hint: a loop) including optimizations... ;)
Posted on 2002-12-06 19:28:35 by stryker
edit: Should have read the post better, I just saw you were using NASM, my post only appies to inline asm in VC (like stryker's example).
:stupid:.


AFAIK it's possible to use the member names even in asm blocks, which is of course much more robust than using hardcoded offsets.
This article...
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_core_accessing_c_or_c.2b2b_.data_in___asm_blocks.asp
... shows you how to use a struct's members in an __asm block. I haven't tested it but I assume it will work for classes as well, since they are more or less the same as structs (just with private instead of public as default access restriction).

Thomas
Posted on 2002-12-07 04:04:29 by Thomas