Search code examples
c++pointersassemblyoffsethybrid

Hybrid program (asm+cpp): sending and receiving an array pointer


(Intel x86. Turbo Assembler and BorlandC compilers, Turbo Linker.)

My question will be about how to modify my f1.asm (and possibly main1.cpp) code.

In main1.cpp I input integer values which I send to function in f1.asm, add them, and send back and display the result in main1.cpp.

main1.cpp:

#include <iostream.h>
#include <stdlib.h>
#include <math.h>

extern "C" int f1(int, int, int);

int main()
{
    int a,b,c;

    cout<<"W = a+b+c" << endl ;
    cout<<"a = " ;
    cin>> a;
    cout<<"b = " ;
    cin>>b;
    cout<<"c = " ;
    cin>>c;

    cout<<"\nW = "<< f1(a,b,c) ;

    return 0;    
}

f1.asm:

.model SMALL, C

.data

.code

PUBLIC f1
f1 PROC

    push    BP
    mov     BP, SP      

    mov ax,[bp+4]
    add ax,[bp+6]
    add ax,[bp+8]

    pop BP
    ret

f1 ENDP

.stack
db 100(?)

END

I want to make such a function for an arbitrary number of variables by sending a pointer to the array of elements to the f1.asm.

QUESTION: If I make the int f1(int, int, int) function in main1.cpp into a int f1( int* ), and put into it the pointer to the array containing the to-be-added values, then how should my .asm code look to access the first (and subsequent) array elements?

How is the pointer stored? Because I tried treating it as an offeset, and an offsett of an offset, and I tried a few other things but I still couldn't access the array's elements.

(If I can just access the first few, I can take care of the rest of the problem.)

...Or should I, in this particular case, use something else from .cpp's side than a pointer?


Solution

  • Ouch, long time I haven't seen a call from 16 bits C to assembly ...

    C or C++ allows passing a variable number of arguments provided callee can determine the number because it pushes all arguments in opposite order before calling the function, and the caller cleans up the stack after the function returned.

    But passing an array is something totally different : you just pass one single value which is the address (a pointer ...) of the array

    Assuming you pass an array of 3 ints - 16 bits small model (int, data pointers, and code addresses are all 16 bits)

    C++

    int arr[3] = {1, 2, 3}
    int cr;
    
    cr = f1(arr);
    

    ASM

    push    BP
    mov     BP, SP      
    
    mov ax,[bp+4]     ; get the address of the array
    mov bp, ax        ; BP now points to the array
    mov ax, [bp]      ; get value of first element
    add ax,[bp+2]     ;   add remaining elements
    add ax,[bp+4]
    
    pop BP
    ret