flat assembler
Message board for the users of flat assembler.

Index > Main > OOP in asm

Author
Thread Post new topic Reply to topic
majidkamali1370



Joined: 31 Oct 2010
Posts: 50
Location: Iran
majidkamali1370 21 Dec 2011, 21:09
Hi.
I created a piece of code that simulates a String class:
Code:
struc String DATA
{
   .str db DATA, '$'
   .len = $ - .str

   .Print:
      mov dx, .str
      mov ah, 9h
      int 21h
      ret
}    

it has two data members and a function.
but when I create that object and call Print function, nothing happens
Code:
mystr String "Hello World !"
call mystr.Print   ;;   <-- This doesn't work    
Post 21 Dec 2011, 21:09
View user's profile Send private message Send e-mail Yahoo Messenger ICQ Number Reply with quote
typedef



Joined: 25 Jul 2010
Posts: 2909
Location: 0x77760000
typedef 21 Dec 2011, 21:18
does it have to do with section setup ? IE, code section and data section?
Post 21 Dec 2011, 21:18
View user's profile Send private message Reply with quote
majidkamali1370



Joined: 31 Oct 2010
Posts: 50
Location: Iran
majidkamali1370 21 Dec 2011, 22:10
in main program, (second snippet) I didn't use sections.
What's difference?
Post 21 Dec 2011, 22:10
View user's profile Send private message Send e-mail Yahoo Messenger ICQ Number Reply with quote
MHajduk



Joined: 30 Mar 2006
Posts: 6115
Location: Poland
MHajduk 21 Dec 2011, 22:23
majidkamali1370 wrote:
Hi.
I created a piece of code that simulates a String class:
Code:
struc String DATA
{
   .str db DATA, '$'
   .len = $ - .str

   .Print:
      mov dx, .str
      mov ah, 9h
      int 21h
      ret
}    

it has two data members and a function.
but when I create that object and call Print function, nothing happens
Code:
mystr String "Hello World !"
call mystr.Print   ;;   <-- This doesn't work    
I'm not sure if this will help in this case but to me you should always jump over the macro instance. Something like this:
Code:
jmp x
mystr String "Hello World !"
x:
call mystr.Print    
Post 21 Dec 2011, 22:23
View user's profile Send private message Visit poster's website Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 21 Dec 2011, 22:23
Code:
struc String DATA
{
   .str db DATA, '$'
   .len = $ - .str

   .Print:
      mov dx, .str
      mov ah, 9h
      int 21h
      ret
}

org $100
; code
call mystr.Print   ;;   <-- This doesn't work
ret

; data
mystr String "Hello World !"      
At least this worked in DOSBox. If your second snippet is literal then your problem is that you are potentially executing the string itself, so it is important you declare the data separately from code (or at least make sure the processor will skip it).

Finally, the method you are using is not so good, if you define ten strings, you will have the printing code duplicated ten times!
Post 21 Dec 2011, 22:23
View user's profile Send private message Reply with quote
majidkamali1370



Joined: 31 Oct 2010
Posts: 50
Location: Iran
majidkamali1370 21 Dec 2011, 23:13
Actually object definition is in another file. here's my whole main program:
Code:
org 100h
jmp start

include 'Fasm Header/Header.inc'

start:
myString String "Hello World!$"
call myString.Print    


object definition is in Header.inc file. (First snippet)
Post 21 Dec 2011, 23:13
View user's profile Send private message Send e-mail Yahoo Messenger ICQ Number Reply with quote
khatch



Joined: 24 Oct 2011
Posts: 74
khatch 21 Dec 2011, 23:39
Hello, majidkamali1370
I found the 2 problems in your code in main.asm ( not 'Fasm Header/Header.inc' )
1) exchange " myString String "Hello World!$" " and " call myString.Print " because making your program execute call instruction not "Hello World!$" as instructions ! Surprised
2) insert between " myString String "Hello World!$" " and " call myString.Print " lines ; " int 20h ; DOS terminate


org 100h
jmp start

include 'Header.inc'

start:

call myString.Print
int 20h
myString String "Hello World!$"


Cool
Post 21 Dec 2011, 23:39
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1635
Location: Toronto, Canada
AsmGuru62 22 Dec 2011, 00:45
Cool!
But the real OOP is in generating FASM code from an OOP script.
That is what I am busy with right now.
But the release is not in sight... Sad
Post 22 Dec 2011, 00:45
View user's profile Send private message Send e-mail Reply with quote
majidkamali1370



Joined: 31 Oct 2010
Posts: 50
Location: Iran
majidkamali1370 23 Dec 2011, 20:46
Thank you guys, but how can I add constructor and destructor to this class ?
Post 23 Dec 2011, 20:46
View user's profile Send private message Send e-mail Yahoo Messenger ICQ Number Reply with quote
JohnFound



Joined: 16 Jun 2003
Posts: 3499
Location: Bulgaria
JohnFound 23 Dec 2011, 20:58
Look, the real OOP is not so simple. The objects contains only data structures and they are allocated dynamically in the run time. This is what constructors and destructors make.
The executable code is not inside the objects. Object oriented languages make it to look like the code is contained in the object, but it is not.
This approach is not possible (but also not needed) for assembly language.
Post 23 Dec 2011, 20:58
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
majidkamali1370



Joined: 31 Oct 2010
Posts: 50
Location: Iran
majidkamali1370 24 Dec 2011, 07:17
So how to manage a big program? (Like an OS)
Post 24 Dec 2011, 07:17
View user's profile Send private message Send e-mail Yahoo Messenger ICQ Number Reply with quote
JohnFound



Joined: 16 Jun 2003
Posts: 3499
Location: Bulgaria
JohnFound 24 Dec 2011, 07:45
How to manage a big program? Well it is a long talk, but "carefully" is my simplest answer. Smile
Post 24 Dec 2011, 07:45
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
typedef



Joined: 25 Jul 2010
Posts: 2909
Location: 0x77760000
typedef 24 Dec 2011, 12:17
OOP in Assembly. Every person originating from HLL universe thinks that way. I did too. While I don't blame you, Assembly is a total different ball game. Everything you want your program to do you must provide the code for yourself in the most portable way possible.
Post 24 Dec 2011, 12:17
View user's profile Send private message Reply with quote
TmX



Joined: 02 Mar 2006
Posts: 841
Location: Jakarta, Indonesia
TmX 24 Dec 2011, 15:39
majidkamali1370 wrote:
So how to manage a big program? (Like an OS)


Well the Linux kernel uses object-oriented design patterns, even though it's written in C

http://lwn.net/Articles/444910/
http://lwn.net/Articles/446317/
Post 24 Dec 2011, 15:39
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4347
Location: Now
edfed 14 Jan 2012, 14:11
now it works:
Code:
        org 100h
struc String DATA
{

        jmp .x
.len    dw .strend-.str
.str    db DATA,'$'
.strend db 0
.Print:
        mov dx, .str
        mov ah, 9h
        int 21h
        ret
.x:
}

        mystr String "Hello World !"
        call mystr.Print
        ret     
    
Post 14 Jan 2012, 14:11
View user's profile Send private message Visit poster's website Reply with quote
tripledot



Joined: 06 Jan 2009
Posts: 49
tripledot 19 Jan 2012, 15:05
Depending on how you want to tackle it, OOP is very easy in FASM...

Code:
struct Foo
  myField dq ?
ends

proc Foo.clear
  virtual at [rbx]
    myFoo Foo
  end virtual
  xor rax, rax
  mov [myFoo.myField], rax
  ret
endp    


You can easily declare methods using the struct name as a prefix, and pass a pointer to the instance in question using any convention you like (for 64 bit Windows, rbx makes a good 'this' pointer):

Code:
clearAllFoos:
  mov rbx, fooArray
  mov rcx, [length]
@@:
  call Foo.clear
  add rbx, sizeof.Foo
  sub rcx, 1
  jnz @b
    
Post 19 Jan 2012, 15:05
View user's profile Send private message Reply with quote
uart777



Joined: 17 Jan 2012
Posts: 369
uart777 23 Jan 2012, 01:37
Is OOP really necessary? Why not just create a structure
with functions? For example, in C... (I hate C++!)

#define structure typedef struct

structure {
void *p;
int x, y, w, h, bpp;
} IMAGE;

void load_image(IMAGE *i, char *file);
void save_image(IMAGE *i, char *file);
void move_image(IMAGE *i, int x, int y);
void draw_image(IMAGE *i);

// ... etc
Post 23 Jan 2012, 01:37
View user's profile Send private message Reply with quote
JohnFound



Joined: 16 Jun 2003
Posts: 3499
Location: Bulgaria
JohnFound 23 Jan 2012, 04:40
OOP is useful sometimes, when you want to manipulate totally different data structures with the same source code. For example, the template engine of FreshLib can build any object and assign its properties without knowledge of the real structure of the object.
Also, OOP helps when you need to build hierarchical system of objects. For example you can create object CommonButton that can be clicked, but can't draw itself on the screen. Then you can create Checkbox as a child class and make it to draw itself as a check box and another class PressButton that looks like normal button.
The advantage here is that "click" functionality need to be implemented only once - in CommonButton class.
IMO, OOP helps when you have to deal with object-like things - GUI widgets are typical example.
Post 23 Jan 2012, 04:40
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
tripledot



Joined: 06 Jan 2009
Posts: 49
tripledot 23 Jan 2012, 11:58
IMO, OOP is a valuable concept to apply to a large project - by its very nature it is designed to help the programmer separate a complex problem into smaller elements.

In a procedural language like assembly, functions can get big and unwieldy quite quickly. When you have a small number of complex functions, each with a large number of tasks, they can become a nightmare to debug or optimise. Example: you find yourself staring into the code, thinking about the best way to reorder a bunch of unrelated instructions. You might see an optimisation, but it's quite likely that you'll overlook algorithmic improvements that might have been more obvious had your source code been cleaner.

But everyone thinks and codes differently. Over-encapsulation can lead to spaghetti nightmares and maintainance headaches, and the thought of dereferencing objects to get pointers to function tables just to normalise a vector gives me the shudders. As assembly programmers, we know the sort of thing a higher-level compiler will spit out, so why should we go to the trouble of writing out the same bloated stuff ourselves?

Much more important than real 'OOP' is a nice logical naming scheme for data and functions. And for critical code, use a neat, fast, register-based calling convention.

My post was just meant to illustrate how fasm's syntax can be used to help maintain sensible naming schemes. If I have two structs, called "Matrix3x3" and "Matrix4x4", and a 'multiply' function for each data type, I would probably name these functions "Matrix3x3.mul" and "Matrix4x4.mul" respectively. It looks a bit like Java's syntax for static methods. In fact, that is what it is! But while static methods in Java are notoriously slow, this approach in fasm just leaves you with neat, tidy procedures that can be called directly, without any horrible function tables.

Like I said, don't make OOP the be-all and end-all of programming. First make your assembly easy to read Smile
Post 23 Jan 2012, 11:58
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.