A Borland 16-bit example… (you would
need 16-bit linker)
//add.c
#include <stdio.h>
int x;
int array[10];
extern void arrayproc(int*,int);
void main(){
int j;
for( j=0;j<10;j++)array[j]=j*100;
arrayproc(array,10);
for( j=0;j<10;j++)printf("%d
",array[j]);
}
;ap.asm
model small
dataseg
newline db 0ah,0dh,'$'
codeseg
PUBLIC _arrayproc
include decout.asm
include macs.asm
_arrayproc proc near
push bp
mov bp,sp
mov di,[bp+4]
mov cx,[bp+6]
looptop:
add word ptr [di],10
inc di
inc di
loop looptop
pop bp
ret
_arrayproc endp
end
Examples from current text. C++
part gets compiled in VC as console project and assembly parts get assembled by
masm/ml.
For visual C:
Build an empty Win32 console project. Here is my test.cpp
extern "C" void
clear();
/*extern
"C" {
void
clear();
}*/
int main() {
clear();
return
1;
}
Over in textpad,
create an assembly module… Here is clear.asm
.586 ;Target
processor. Use instructions for Pentium
class machines
.MODEL FLAT, C ;Use
the flat memory model. Use C calling conventions
.STACK ;Define
a stack segment of 1KB (Not required for this example)
.DATA ;Create
a near data segment. Local variables are
declared after
;this
directive (Not required for this example)
.CODE ;Indicates
the start of a code segment.
clear PROC
xor eax, eax
xor ebx, ebx
ret
clear ENDP
END
If you can run ml (on your own computer) assemble (only) this file. Do not link because there is no entry point. Copy the obj file to your VC++ project
Here is my project:
I then ran it without debug – black screen opens. It doesn’t do anything.
Next example (from text) passing arguments to a function
C++ main:
#include <iostream>
using namespace std;
extern "C" int addem(int p1, int p2, int p3);
int main()
{ int total = addem( 10, 15, 25 );
cout << "Total = " << total << endl;
return 0;
}
Assembly subroutine
title The addem Subroutine (addem.asm)
; This subroutine links to Visual C++ 6.0.
.386P
.model flat
public _addem
.code
_addem proc near
push ebp
mov ebp,esp
mov eax,[ebp+16] ; first argument
add eax,[ebp+12] ; second argument
add eax,[ebp+8] ; third argument
pop ebp
ret
_addem endp
end
//header
void TranslateBuffer( char * buf, unsigned count,
unsigned char eChar );
//inline assembly module
#include "translat.h"
/* Translate a buffer of <count> bytes, using an encryption
character <eChar>. Uses an XOR operation (ASM function).*/
void TranslateBuffer( char * buf, unsigned count,
unsigned char eChar )
{
__asm {
mov esi,buf ; set index register
mov ecx,count /* set loop counter */
mov al,eChar
L1:
xor [esi],al
inc esi
Loop L1
} // asm
}
//c++
#include <iostream>
#include <fstream>
#include "translat.h"
using namespace std;
int main( int argcount, char * args[] )
{
// Read input and output files from the command line.
if( argcount < 3 ) {
cout << "Usage: encode infile outfile" << endl;
return -1;
}
const int BUFSIZE = 2000;
char buffer[BUFSIZE];
unsigned int count; // character count
unsigned char encryptCode;
cout << "Encryption code [0-255]? ";
cin >> encryptCode;
ifstream infile( args[1], ios::binary );
ofstream outfile( args[2], ios::binary );
cout << "Reading " << args[1] << " and creating "
<< args[2] << endl;
while (!infile.eof() )
{
infile.read(buffer, BUFSIZE );
count = infile.gcount();
TranslateBuffer(buffer, count, encryptCode);
outfile.write(buffer, count);
}
return 0;
}