Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

ASM functions in C++, how?

wArewAre Member Posts: 46
I bought this self-study assembly book, that had MASM 6.11 in it's CD. I started to study, and later on noticed, that the assembler produced DOS programs. That's ok, but now I'm in a point, where I'd like to try to add my asm-progs to C++ apps. I dug out my old Borland C++ 3.1, and wrote some code, but I don't have a clue, how to use DOS based assembler progs from C++ apps. All I know is that memory model has something to do with the fact that the params are pushed to stack, but that's really all I know. Can anyone help me? Thanks in advance...
[italic][blue]
wAre
Beginner Programmmer
[/blue][/italic]

Comments

  • BitdogBitdog Member Posts: 528
    : I bought this self-study assembly book, that had MASM 6.11 in it's CD. I started to study, and later on noticed, that the assembler produced DOS programs. That's ok, but now I'm in a point, where I'd like to try to add my asm-progs to C++ apps. I dug out my old Borland C++ 3.1, and wrote some code, but I don't have a clue, how to use DOS based assembler progs from C++ apps. All I know is that memory model has something to do with the fact that the params are pushed to stack, but that's really all I know. Can anyone help me? Thanks in advance...
    : [italic][blue]
    : wAre
    : Beginner Programmmer
    : [/blue][/italic]
    [green]
    AsmGuru62 is probably your man for this question, but I got free time,
    and maybe he'll add to this.
    You can use an inline assembler to put code directly into your C code.
    You can also use your Masm to create linkable librarys
    which is basicly .ASM code snipits assembled into .OBJ files
    and LIB.EXE crouds them into a library.
    Then I think your C code includes them defined as an EXTERNAL or something
    and you can call & use them just as you would call & use a C routine/PROC

    The model you use in C, or the compiler you use, or ?
    dictates how many words are pushed on the stack when a PROC is called/used
    So your .ASM code has to work around that.
    A near call pushes the OFFSET RETurn address which is a word or INT in size = two bytes (2 CHAR's)
    So your .ASM code needs a pointer to it, & BP is often used

    PROC:
    PUSH BP
    MOV BP,SP ;BP is your pointer
    MOV AX,[BP+4] ;get a word input into AX
    MOV CX,[BP+6] ;get another word

    ;your code here

    POP BP
    RET

    ok that's the general idea for a near call, & probably wrong so experiment.
    compile/assemble a small something, & debug it,
    watch your stack pointer before & after a call to insure it's not altered.
    Watch what [BP+4] or +6 or +8 etc get's you.
    Inother words load some hex values as input 11h 22h 33h 44h
    so it clearly shows up on your debugger, then you'll know.

    There might be a way to use the version of Masm you have as an inline
    assembler using an IDE interface thingie.
    Also there are better versions of Masm available on the internet.
    I got a MASM32 environment ready to goto work the other day and it
    was quite impressive. www.google.com search might get it.

    If I stop here, I'll have less mistakes & less bad info for you.
    Good luck
    Bitdog
    [/green]

  • AsmGuru62AsmGuru62 Member Posts: 6,519
    : : I bought this self-study assembly book, that had MASM 6.11 in it's CD. I started to study, and later on noticed, that the assembler produced DOS programs. That's ok, but now I'm in a point, where I'd like to try to add my asm-progs to C++ apps. I dug out my old Borland C++ 3.1, and wrote some code, but I don't have a clue, how to use DOS based assembler progs from C++ apps. All I know is that memory model has something to do with the fact that the params are pushed to stack, but that's really all I know. Can anyone help me? Thanks in advance...
    : : [italic][blue]
    : : wAre
    : : Beginner Programmmer
    : : [/blue][/italic]
    : [green]
    : AsmGuru62 is probably your man for this question, but I got free time,
    : and maybe he'll add to this.
    : You can use an inline assembler to put code directly into your C code.
    : You can also use your Masm to create linkable librarys
    : which is basicly .ASM code snipits assembled into .OBJ files
    : and LIB.EXE crouds them into a library.
    : Then I think your C code includes them defined as an EXTERNAL or something
    : and you can call & use them just as you would call & use a C routine/PROC
    :
    : The model you use in C, or the compiler you use, or ?
    : dictates how many words are pushed on the stack when a PROC is called/used
    : So your .ASM code has to work around that.
    : A near call pushes the OFFSET RETurn address which is a word or INT in size = two bytes (2 CHAR's)
    : So your .ASM code needs a pointer to it, & BP is often used
    :
    : PROC:
    : PUSH BP
    : MOV BP,SP ;BP is your pointer
    : MOV AX,[BP+4] ;get a word input into AX
    : MOV CX,[BP+6] ;get another word
    :
    : ;your code here
    :
    : POP BP
    : RET
    :
    : ok that's the general idea for a near call, & probably wrong so experiment.
    : compile/assemble a small something, & debug it,
    : watch your stack pointer before & after a call to insure it's not altered.
    : Watch what [BP+4] or +6 or +8 etc get's you.
    : Inother words load some hex values as input 11h 22h 33h 44h
    : so it clearly shows up on your debugger, then you'll know.
    :
    : There might be a way to use the version of Masm you have as an inline
    : assembler using an IDE interface thingie.
    : Also there are better versions of Masm available on the internet.
    : I got a MASM32 environment ready to goto work the other day and it
    : was quite impressive. www.google.com search might get it.
    :
    : If I stop here, I'll have less mistakes & less bad info for you.
    : Good luck
    : Bitdog
    : [/green]
    :
    :
    [blue]If we talking about the ASM code which you compile outside of C/C++ - then I never do that - a lot of effort and nothing to gain.

    If we talking to use the inline ASM in C/C++ then fire your questions at me!..
    [/blue]
  • BitdogBitdog Member Posts: 528
    [blue]
    If we talking to use the inline ASM in C/C++
    then fire off some questions
    [/blue]
    (Yer Xmas altered quote.)
    [green]
    Ok, I got a question........
    Can he get his Masm 6.11 to do inline assembly in Borland C++ 3.1 compiler?
    If so how ? (quickie sumation is fine)
    #2 why doesn't he get Tasm or Turbo Tasm which should
    work with his Borland C++ 3.1
    It's free now a days & uses almost identical syntaxes to Masm.
    [/green]

  • AsmGuru62AsmGuru62 Member Posts: 6,519
    [b][red]This message was edited by AsmGuru62 at 2003-12-12 9:28:52[/red][/b][hr]
    : [blue]
    : If we talking to use the inline ASM in C/C++
    : then fire off some questions
    : [/blue]
    : (Yer Xmas altered quote.)
    : [green]
    : Ok, I got a question........
    : Can he get his Masm 6.11 to do inline assembly in Borland C++ 3.1 compiler?
    : If so how ? (quickie sumation is fine)
    : #2 why doesn't he get Tasm or Turbo Tasm which should
    : work with his Borland C++ 3.1
    : It's free now a days & uses almost identical syntaxes to Masm.
    : [/green]
    :
    :
    [blue]If I am not mistaken, since BC 3.1 - it has its own (internal) ASM engine, so you do not have to keep the TASM in your BC 3.1 BIN folder. I may be mistaken... it was long ago... let me get back to you... I check on my BC 3.1 right now.

    P.S. I do not have any TASM in my BC 3.1 - yet all [b]_asm[/b] code compiles fine.[/blue]


  • xkgdiamxkgdiam Member Posts: 111
    [b][red]This message was edited by xkgdiam at 2003-12-12 22:22:53[/red][/b][hr]
    : : I bought this self-study assembly book, that had MASM 6.11 in it's CD. I started to study, and later on noticed, that the assembler produced DOS programs. That's ok, but now I'm in a point, where I'd like to try to add my asm-progs to C++ apps. I dug out my old Borland C++ 3.1, and wrote some code, but I don't have a clue, how to use DOS based assembler progs from C++ apps. All I know is that memory model has something to do with the fact that the params are pushed to stack, but that's really all I know. Can anyone help me? Thanks in advance...
    : : [italic][blue]
    : : wAre
    : : Beginner Programmmer
    : : [/blue][/italic]
    : [green]
    : AsmGuru62 is probably your man for this question, but I got free time,
    : and maybe he'll add to this.
    : You can use an inline assembler to put code directly into your C code.
    : You can also use your Masm to create linkable librarys
    : which is basicly .ASM code snipits assembled into .OBJ files
    : and LIB.EXE crouds them into a library.
    : Then I think your C code includes them defined as an EXTERNAL or something
    : and you can call & use them just as you would call & use a C routine/PROC
    :
    : The model you use in C, or the compiler you use, or ?
    : dictates how many words are pushed on the stack when a PROC is called/used
    : So your .ASM code has to work around that.
    : A near call pushes the OFFSET RETurn address which is a word or INT in size = two bytes (2 CHAR's)
    : So your .ASM code needs a pointer to it, & BP is often used
    :
    : PROC:
    : PUSH BP
    : MOV BP,SP ;BP is your pointer
    : MOV AX,[BP+4] ;get a word input into AX
    : MOV CX,[BP+6] ;get another word
    :
    : ;your code here
    :
    : POP BP
    : RET
    :
    : ok that's the general idea for a near call,

    the general idea for far code is just the same
    but the first argument is at [bp+6]
    the above sceme must always be this for your asm code,
    otherwise no function will work
    i have create a mocro for myself that makes my asm code
    the same both on small or large models
    first this :
    [code]
    ifdef __LARGE__
    .model large
    return equ retf
    _CSonStack equ 2 ;means CS is also pushed before call
    else
    .model small
    return equ ret
    _CSonStack equ 0
    endif

    then my initialize the stuck macro:
    pushStack macro
    push bp
    mov bp,sp ;
    add bp,4 ;IP was pushed / BP was pushed
    add bp,_CSonStack ;in LARGE model CS is pushed also, so SP+=2
    ;now the first arg is at [bp],2nd [bp+2],....
    endm

    and finaly:
    popStack macro
    push bp
    endm

    So, all my extern asm code seems like that
    public _myfunction ;to be found by the linker
    _myfunction: ;use '_' so you can call inside C/C++
    pushStack
    mov ax,[bp] ; 1st arg
    mov cx,[bp+2] ; 2nd arg
    ;...my code
    mov ax,10h ; the return code is a 16bit value 0x0010
    ;or ; -dx--ax-
    mov dx,20h ; the return is a 32bit value 0x00200010
    popStack
    return
    and nothing is too change, if the model change
    declare the function in C:
    extern int myfunction(int 1st_arg,int 2nd_arg);
    or in C++ :
    extern "C" int myfunction(int .....,...);

    that returns the AX, for a long (DX:AX)
    extern long myfunction(int 1st_arg,int 2nd_arg);

    Note, if you have an asm function
    extern int function1(char 1st_arg);
    then your C/C++ code will push a 16bit value on the stack,again
    so use again
    mov ax,[bp] ; the 1st_arg is in AL

    And last C/C++ push arguments on the stack from right to left

    The link :
    small model
    tcc /ms myc.cpp myasm.asm
    large model
    tcc /ml myc.cpp myasm.asm

    or
    small model
    tasm -D__SMALL__ myasm.asm
    tcc /ms -c- myc.cpp
    tlink myc myasm c0s,,,cs.lib
    large model
    tasm -D__LARGE__ myasm.asm
    tcc /ml -c- myc.cpp
    tlink myc myasm c0l,,,cl.lib
    [/code]




  • wArewAre Member Posts: 46
    : [b][red]This message was edited by xkgdiam at 2003-12-12 22:22:53[/red][/b][hr]
    : : : I bought this self-study assembly book, that had MASM 6.11 in it's CD. I started to study, and later on noticed, that the assembler produced DOS programs. That's ok, but now I'm in a point, where I'd like to try to add my asm-progs to C++ apps. I dug out my old Borland C++ 3.1, and wrote some code, but I don't have a clue, how to use DOS based assembler progs from C++ apps. All I know is that memory model has something to do with the fact that the params are pushed to stack, but that's really all I know. Can anyone help me? Thanks in advance...
    : : : [italic][blue]
    : : : wAre
    : : : Beginner Programmmer
    : : : [/blue][/italic]
    : : [green]
    : : AsmGuru62 is probably your man for this question, but I got free time,
    : : and maybe he'll add to this.
    : : You can use an inline assembler to put code directly into your C code.
    : : You can also use your Masm to create linkable librarys
    : : which is basicly .ASM code snipits assembled into .OBJ files
    : : and LIB.EXE crouds them into a library.
    : : Then I think your C code includes them defined as an EXTERNAL or something
    : : and you can call & use them just as you would call & use a C routine/PROC
    : :
    : : The model you use in C, or the compiler you use, or ?
    : : dictates how many words are pushed on the stack when a PROC is called/used
    : : So your .ASM code has to work around that.
    : : A near call pushes the OFFSET RETurn address which is a word or INT in size = two bytes (2 CHAR's)
    : : So your .ASM code needs a pointer to it, & BP is often used
    : :
    : : PROC:
    : : PUSH BP
    : : MOV BP,SP ;BP is your pointer
    : : MOV AX,[BP+4] ;get a word input into AX
    : : MOV CX,[BP+6] ;get another word
    : :
    : : ;your code here
    : :
    : : POP BP
    : : RET
    : :
    : : ok that's the general idea for a near call,
    :
    : the general idea for far code is just the same
    : but the first argument is at [bp+6]
    : the above sceme must always be this for your asm code,
    : otherwise no function will work
    : i have create a mocro for myself that makes my asm code
    : the same both on small or large models
    : first this :
    : [code]
    : ifdef __LARGE__
    : .model large
    : return equ retf
    : _CSonStack equ 2 ;means CS is also pushed before call
    : else
    : .model small
    : return equ ret
    : _CSonStack equ 0
    : endif
    :
    : then my initialize the stuck macro:
    : pushStack macro
    : push bp
    : mov bp,sp ;
    : add bp,4 ;IP was pushed / BP was pushed
    : add bp,_CSonStack ;in LARGE model CS is pushed also, so SP+=2
    : ;now the first arg is at [bp],2nd [bp+2],....
    : endm
    :
    : and finaly:
    : popStack macro
    : push bp
    : endm
    :
    : So, all my extern asm code seems like that
    : public _myfunction ;to be found by the linker
    : _myfunction: ;use '_' so you can call inside C/C++
    : pushStack
    : mov ax,[bp] ; 1st arg
    : mov cx,[bp+2] ; 2nd arg
    : ;...my code
    : mov ax,10h ; the return code is a 16bit value 0x0010
    : ;or ; -dx--ax-
    : mov dx,20h ; the return is a 32bit value 0x00200010
    : popStack
    : return
    : and nothing is too change, if the model change
    : declare the function in C:
    : extern int myfunction(int 1st_arg,int 2nd_arg);
    : or in C++ :
    : extern "C" int myfunction(int .....,...);
    :
    : that returns the AX, for a long (DX:AX)
    : extern long myfunction(int 1st_arg,int 2nd_arg);
    :
    : Note, if you have an asm function
    : extern int function1(char 1st_arg);
    : then your C/C++ code will push a 16bit value on the stack,again
    : so use again
    : mov ax,[bp] ; the 1st_arg is in AL
    :
    : And last C/C++ push arguments on the stack from right to left
    :
    : The link :
    : small model
    : tcc /ms myc.cpp myasm.asm
    : large model
    : tcc /ml myc.cpp myasm.asm
    :
    : or
    : small model
    : tasm -D__SMALL__ myasm.asm
    : tcc /ms -c- myc.cpp
    : tlink myc myasm c0s,,,cs.lib
    : large model
    : tasm -D__LARGE__ myasm.asm
    : tcc /ml -c- myc.cpp
    : tlink myc myasm c0l,,,cl.lib
    : [/code]
    :
    :
    :
    :
    :
    OK, I have two questions now. Let's say that I write a function in ASM, that takes a pointer as a parameter, and I call it from C/C++ program. How do I take the segment and offset from the parameter, in LARGE memory model? Second question is bit alike. If I have a DWORD that has a pointer in it, how do I separate segment and offset?

    [italic][blue]
    wAre
    Beginner Programmmer
    [/blue][/italic]


  • AsmGuru62AsmGuru62 Member Posts: 6,519
    : : [b][red]This message was edited by xkgdiam at 2003-12-12 22:22:53[/red][/b][hr]
    : : : : I bought this self-study assembly book, that had MASM 6.11 in it's CD. I started to study, and later on noticed, that the assembler produced DOS programs. That's ok, but now I'm in a point, where I'd like to try to add my asm-progs to C++ apps. I dug out my old Borland C++ 3.1, and wrote some code, but I don't have a clue, how to use DOS based assembler progs from C++ apps. All I know is that memory model has something to do with the fact that the params are pushed to stack, but that's really all I know. Can anyone help me? Thanks in advance...
    : : : : [italic][blue]
    : : : : wAre
    : : : : Beginner Programmmer
    : : : : [/blue][/italic]
    : : : [green]
    : : : AsmGuru62 is probably your man for this question, but I got free time,
    : : : and maybe he'll add to this.
    : : : You can use an inline assembler to put code directly into your C code.
    : : : You can also use your Masm to create linkable librarys
    : : : which is basicly .ASM code snipits assembled into .OBJ files
    : : : and LIB.EXE crouds them into a library.
    : : : Then I think your C code includes them defined as an EXTERNAL or something
    : : : and you can call & use them just as you would call & use a C routine/PROC
    : : :
    : : : The model you use in C, or the compiler you use, or ?
    : : : dictates how many words are pushed on the stack when a PROC is called/used
    : : : So your .ASM code has to work around that.
    : : : A near call pushes the OFFSET RETurn address which is a word or INT in size = two bytes (2 CHAR's)
    : : : So your .ASM code needs a pointer to it, & BP is often used
    : : :
    : : : PROC:
    : : : PUSH BP
    : : : MOV BP,SP ;BP is your pointer
    : : : MOV AX,[BP+4] ;get a word input into AX
    : : : MOV CX,[BP+6] ;get another word
    : : :
    : : : ;your code here
    : : :
    : : : POP BP
    : : : RET
    : : :
    : : : ok that's the general idea for a near call,
    : :
    : : the general idea for far code is just the same
    : : but the first argument is at [bp+6]
    : : the above sceme must always be this for your asm code,
    : : otherwise no function will work
    : : i have create a mocro for myself that makes my asm code
    : : the same both on small or large models
    : : first this :
    : : [code]
    : : ifdef __LARGE__
    : : .model large
    : : return equ retf
    : : _CSonStack equ 2 ;means CS is also pushed before call
    : : else
    : : .model small
    : : return equ ret
    : : _CSonStack equ 0
    : : endif
    : :
    : : then my initialize the stuck macro:
    : : pushStack macro
    : : push bp
    : : mov bp,sp ;
    : : add bp,4 ;IP was pushed / BP was pushed
    : : add bp,_CSonStack ;in LARGE model CS is pushed also, so SP+=2
    : : ;now the first arg is at [bp],2nd [bp+2],....
    : : endm
    : :
    : : and finaly:
    : : popStack macro
    : : push bp
    : : endm
    : :
    : : So, all my extern asm code seems like that
    : : public _myfunction ;to be found by the linker
    : : _myfunction: ;use '_' so you can call inside C/C++
    : : pushStack
    : : mov ax,[bp] ; 1st arg
    : : mov cx,[bp+2] ; 2nd arg
    : : ;...my code
    : : mov ax,10h ; the return code is a 16bit value 0x0010
    : : ;or ; -dx--ax-
    : : mov dx,20h ; the return is a 32bit value 0x00200010
    : : popStack
    : : return
    : : and nothing is too change, if the model change
    : : declare the function in C:
    : : extern int myfunction(int 1st_arg,int 2nd_arg);
    : : or in C++ :
    : : extern "C" int myfunction(int .....,...);
    : :
    : : that returns the AX, for a long (DX:AX)
    : : extern long myfunction(int 1st_arg,int 2nd_arg);
    : :
    : : Note, if you have an asm function
    : : extern int function1(char 1st_arg);
    : : then your C/C++ code will push a 16bit value on the stack,again
    : : so use again
    : : mov ax,[bp] ; the 1st_arg is in AL
    : :
    : : And last C/C++ push arguments on the stack from right to left
    : :
    : : The link :
    : : small model
    : : tcc /ms myc.cpp myasm.asm
    : : large model
    : : tcc /ml myc.cpp myasm.asm
    : :
    : : or
    : : small model
    : : tasm -D__SMALL__ myasm.asm
    : : tcc /ms -c- myc.cpp
    : : tlink myc myasm c0s,,,cs.lib
    : : large model
    : : tasm -D__LARGE__ myasm.asm
    : : tcc /ml -c- myc.cpp
    : : tlink myc myasm c0l,,,cl.lib
    : : [/code]
    : :
    : :
    : :
    : :
    : :
    : OK, I have two questions now. Let's say that I write a function in ASM, that takes a pointer as a parameter, and I call it from C/C++ program. How do I take the segment and offset from the parameter, in LARGE memory model? Second question is bit alike. If I have a DWORD that has a pointer in it, how do I separate segment and offset?
    :
    : [italic][blue]
    : wAre
    : Beginner Programmmer
    : [/blue][/italic]
    :
    :
    :
    [blue]The [b]far[/b] pointer in memory looks like "OFFSET:SEGMENT" (backwards), so:
    [code]
    .DATA
    dwPointer dd ?
    .CODE
    mov dx, word ptr [dwPointer] ; OFFSET
    mov ax, word ptr [dwPointer+2] ; SEGMENT

    ; --- OR...

    les di, dwPointer ; ES:DI is SEG:OFS as usual
    [/code]
    [/blue]
Sign In or Register to comment.