🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.cppbuilder.language.basm
8 messages
8 total messages Started by Daniel Thu, 13 Sep 2007 14:22
integrating assembly and C++ Builder 6
#33
Author: Daniel
Date: Thu, 13 Sep 2007 14:22
20 lines
1953 bytes
I'm working on writing some assembly modules that I want to integrate with a
C++ Builder 6 application as part of a learning project so I can maintain
some existing code.

I've found that I can compile an assembly program from the IDE, presumably
because the IDE calls TASM32 when it builds a project. I can also call
TASM32 from the command line.

But I get an error about "symbol __PublicInfoTable defined in both
filename.obj and ...Borland\Lib\COW32.obj" where the filename.obj is my
assembly file. Although the IDE generates an executable it doesn't run as it
should (the screen flashes, but the main form never comes up). If I remove
the assembly module from the project and comment out the extern references
to it from the C++ side the project builds and runs fine.

Naturally Borland doesn't cover this and neither do any of the eight
reference books including Borlands Turbo Assembler Users Guide or Tom Swan's
Mastering Turbo Assembler, neither of which cover Builder 6.

Does anyone have suggestions for doing what I'm trying to do?
Re: integrating assembly and C++ Builder 6
#32
Author: Bob Gonder
Date: Thu, 13 Sep 2007 14:39
8 lines
1257 bytes
Daniel wrote:

>But I get an error about "symbol __PublicInfoTable defined in both
>filename.obj and ...Borland\Lib\COW32.obj"

Does your Asm module contain or use that name?
define it external in your asm.
	extrn	__PublicInfoTable:dword ;or whatever
Re: integrating assembly and C++ Builder 6
#34
Author: Daniel
Date: Thu, 13 Sep 2007 15:51
40 lines
2342 bytes
No, I don't use that in the assembly module. The assembly module is extremly
simple:
.386
.model flat
PUBLIC _externproc
DATASEG
;one or two things here just to define something.
ENDS DATA
CODE
mov eax, 05Ah; just to have something happen
ENDS CODE
END

patterned after a previous post on this group. I created this file by
choosing File->New->Assembly then adding it to the project. Although I can
assemble it with the command-line assembler and add the object file to the
Builder project, it doesn't make any difference whether the asm file or obj
file is part of the project.

Borland's documentation advises to use the same .model in the assembly
module as the C++ program, but nowhere in Builder does it give any
indication of what the model is. Nor can I find anything that says anything
about what the COW32.obj file might be or do.

Any help is much appreciated since I'm going nuts.

D

"Bob Gonder" <notbg@notmindspring.invalid> wrote in message
news:ahiie31op322c33qt9t70a4jfu67mto5ih@4ax.com...
> Daniel wrote:
>
> >But I get an error about "symbol __PublicInfoTable defined in both
> >filename.obj and ...Borland\Lib\COW32.obj"
>
> Does your Asm module contain or use that name?
> define it external in your asm.
> extrn __PublicInfoTable:dword ;or whatever
>
>
Re: integrating assembly and C++ Builder 6
#35
Author: Ed Mulroy [TeamB]
Date: Thu, 13 Sep 2007 19:10
100 lines
4185 bytes
In what you show you have PUBLIC _externproc  The PUBLIC line is a 
declaration that a symbol is to be placed into the public symbol table.  It 
is not a declaration of the symbol.  I think _externproc should be a 
procedure (a proc) in the code.

As an example, here is some assembly that does that.  Unlike your code it 
actually declares segments instead of using the "simplified" directives that 
you seem to prefer.  The comments about the symbols are not related to the 
difference in segment declaration.  They refer to the symbol WinMain.

----------------------------
        .386p
        model flat

HWND_DESKTOP    equ   0
MB_OK           equ   0

_TEXT   segment dword public use32 'CODE'
_TEXT   ends
_DATA   segment dword public use32 'DATA'
_DATA   ends
_BSS    segment dword public use32 'BSS'
_BSS    ends

; This program does not use _BSS, the unitialized global data segment,
; but is generally needed in programs so I've added it here
DGROUP  group   _BSS,_DATA

        ; declaration of Windows' ascii MessageBox function
        ; the linker will find a reference to it in the Windows import 
library

        extrn   MessageBoxA     :near

_DATA   segment dword public use32 'DATA'
        align   1
msg     db      " Hello World! ",0
mtitle  db      "Hello Message Box", 0
zero    dw      0
        align   4
_DATA   ends


_TEXT   segment dword public use32 'CODE'
WinMain proc    near
        push    ebp       ; save EBP register and load stack ptr into it
        mov     ebp,esp

        ; MessageBox(HWND_DESKTOP, msg, mtitle, MB_OK);
        push    MB_OK
        push    offset mtitle
        push    offset msg
        push    HWND_DESKTOP
        call    MessageBoxA

        xor     eax,eax  ; return value is zero
        pop     ebp      ; restore EBP register value
        ret     16       ; free up 16 bytes of stack when returning
WinMain endp
_TEXT   ends

        public  WinMain

        end     WinMain
----------------------------


.  Ed

> Daniel wrote in message
> news:46e95c9e@newsgroups.borland.com...
>
> No, I don't use that in the assembly module. The assembly module
> is extremly
> simple:
> .386
> .model flat
> PUBLIC _externproc
> DATASEG
> ;one or two things here just to define something.
> ENDS DATA
> CODE
> mov eax, 05Ah; just to have something happen
> ENDS CODE
> END
>
> patterned after a previous post on this group. I created this file by
> choosing File->New->Assembly then adding it to the project. Although I can
> assemble it with the command-line assembler and add the object file to the
> Builder project, it doesn't make any difference whether the asm file or 
> obj
> file is part of the project.
>
> Borland's documentation advises to use the same .model in the assembly
> module as the C++ program, but nowhere in Builder does it give any
> indication of what the model is. Nor can I find anything that says 
> anything
> about what the COW32.obj file might be or do.
>
> Any help is much appreciated since I'm going nuts.
Re: integrating assembly and C++ Builder 6
#36
Author: Bob Gonder
Date: Fri, 14 Sep 2007 01:56
21 lines
1727 bytes
Daniel wrote:

>PUBLIC _externproc

_externproc must be a label in your asm module (you are exporting it).

>Borland's documentation advises to use the same .model in the assembly
>module as the C++ program, but nowhere in Builder does it give any
>indication of what the model is.

BCB only uses FLAT
In the DOS days, we had more choices.

> Nor can I find anything that says anything
>about what the COW32.obj file might be or do.

CzeroW32 is the 32 bit Windows startup(C0) code
for programs that start at WinMain.

C0X32 is the 32 bit Console startup code
for programs that start at Main.
Re: integrating assembly and C++ Builder 6
#37
Author: Daniel deLesdernier
Date: Fri, 14 Sep 2007 14:17
76 lines
3871 bytes
You are already clearing up a few questions, for which I thank you.
The asm code currently reads thusly:
.386p
PUBLIC _externproc
DATASEG
_asmNum DD 0505Ah;just to see if this works
ENDS _DATA
CODESEG
start:
_externproc PROC
mov as, 05h
ret
-externproc ENDP
ENDS _TEXT
END start

This is an asm file in a Builder Project that has a single, default form,
with an edit box and one event handler:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
int num1=78;
int num2=0;
char *myChar[1];
Form1->Edit1->Text="6";
asm mov eax,num1
asm mov eax, 0Ah
asm mov num2,eax
asm mov eax,0FFh
asm mov myChar, eax
asm mov eax,myChar
asm mov num2,eax
externproc();
Form1->Edit1->Text=num2;
}

Also before the C++ code I declare externproc with

extern "C" void externproc();

Again, the program isn't meant to do much yet; I'm trying to figure out how
to structure things first.

This version actually compiles, links, and runs!!! But why?

Now, before I had a start: directive just before _externproc Proc and an
ENDS start at the very end and I was getting the error ("publicInfoTable
defined in both module externproc.obj and C0W32.obj). Is this possibly
because the start: directive was inserting a bunch of startup stuff into the
obj file that Builder automatically inserts in an application from the
C0W32.obj file when it links and builds the application?

Also, PUBLIC _externproc is necessary, I think, to get the linker to find
the function implementation since it is not in the cpp file. What is it you
said about the PUBLIC directive putting something in a symbol table? What's
a symbol table?

You mentioned in an earlier post about declaring segments with the
simplified directives which I might prefer. I don't really care; I'm
struggling to get something working without adequate documentation. It is
frustrating to have Borland's web site suggest books that are out of date or
out of print. Even Mastering Turbo Assembler is only of limited help because
none of the example code compiles and runs (it seems to all be 16-bit? and
all Builder 6 gives you is tasm32). So before you can learn anything from
the examples you have to learn a lot of other stuff just to get the examples
to run (which I haven't been able to do yet). But I digress. Are there
advantages to not using the simplified directives? Perhaps it allows you to
put code and data in muliple places in your source file (in a way that makes
sense to you) and then have the linker put everything together in computer
memory whereas using the simplified directives forces you to type in all
your data and code in either the CODESEG or DATASEG? Can you use CODESEG and
DATASEG multiple times in a source file?

Thanks,

Daniel deLesdernier
Re: integrating assembly and C++ Builder 6
#38
Author: Bob Gonder
Date: Fri, 14 Sep 2007 22:51
101 lines
3664 bytes
Daniel deLesdernier wrote:

>.386p

You forgot the Model

>PUBLIC _externproc

I prefer to put my Publics in the same segment as the actual label.
CODESEG
    PUBLIC	_externproc

>DATASEG
>_asmNum DD 0505Ah;just to see if this works
>ENDS _DATA
>CODESEG
>start:
>_externproc PROC
>mov as, 05h

That's not an instruction.

>ret
>-externproc ENDP

Wrong, probably because you typed it in.
Always use copy/paste for code.

>ENDS _TEXT
>END start

Illegal for subroutine modules.
"END start" is for stand-alone applications such as the original *.com files
Use just plain end
	end	;End Of File


>void __fastcall TForm1::Button1Click(TObject *Sender)
>{
>int num1=78;
>int num2=0;
>char *myChar[1];
>Form1->Edit1->Text="6";

Please use Asm blocks:
asm{	code
	code
        };

>asm mov eax,num1

Redundant as you immediately overwrite eax in the next instruction

>asm mov eax, 0Ah
>asm mov num2,eax

Much easier to do
	mov	num2,0ah

>asm mov eax,0FFh
>asm mov myChar, eax

Not a good idea.
myChar now points to memory location 0xFF

>extern "C" void externproc();

Correct.

>This version actually compiles, links, and runs!!! But why?

Why not?

>Also, PUBLIC _externproc is necessary, I think, to get the linker to find
>the function implementation since it is not in the cpp file. What is it you
>said about the PUBLIC directive putting something in a symbol table? What's
>a symbol table?

In ASM, everything in your code is private to the file unless you explicitly
say otherwise.  In C/C++, everthing is Public unless told otherwise.

When the assembler creates the OBJ file, it won't put in anything
telling the linker the names of the private items.  The place where
the assembler (or any compiler of that matter) places those names
is called the symbol table, and is a part of the OBJ file.

In order for any other module to see _externproc, you must tell the
assembler that you mean to share it.

> Are there
>advantages to not using the simplified directives?

You can have more control, but most of the time, the default behaviour
of the simplified directives is more than adequate.
Ed likes to wield total control over his ASM.

>Can you use CODESEG and DATASEG multiple times in a source file?

Yes, and don't forget the UDATASEG for those uninitialized variables.
Hard coded empty arrays should go in the UDATASEG so they don't
take up space in the EXE file.
Re: integrating assembly and C++ Builder 6
#39
Author: Daniel deLesdernier
Date: Mon, 17 Sep 2007 14:42
20 lines
1993 bytes
Thanks so much for your help. Now that I have something basically working
I'm in a better position to dig deeper.

To respond to just a couple of things you raised (not sure if this is the
proper use of a posting).

Why shouldn't my little program have compiled and run? I was startled when
it did since I'd been struggling with it for days and wasn't sure why
removing the start: label should have much such a difference. It seems so
small a thing.

On using ASM blocks inline: that makes more sense to me, but I'm working on
documentating and maintaing code that wasn't done this way and I wanted to
understand how it was done in case there were good reasons for it before
making changes.

Thanks again. I may have need of you help again at some point.

"Bob Gonder" <notbg@notmindspring.invalid> wrote in message
news:2e2me3t6kfas0t0e6krtesf3vut1q74fkv@4ax.com...
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads