Hi,
My task is to create a library/precompiled header for use with MASM. I am using Code:Blocks. I have googled quite a bit and haven't come up with an appropriate solution. I was hoping someone could point me in the right direction. This is what i have done so far:

1)Created a Static Library from Code blocks,
2)Written a little snippet in it consisting of two small functions,
3)Compiled the file.

This results in a libxxx.a file in the Debug folder. I want the library to be in such a format that it can be recognized and called by MASM.

Secondly, while we're on the topic, please clear out a little confusion: dont libraries consist of header files? Why is it, when i chose to write a "static library" that I was given a .c file?

Recommended Answers

All 18 Replies

AFAIK masm only works with *.lib libraries built with Microsoft compilers or other compilers that create libraries in that format. Download and isntall the free Visual Studio 2013 Express.

ont libraries consist of header files?

They are compiled *.c files. You will have to create the header file manually yourself -- it's just a normal text file with *.h file extension.

Why is it, when i chose to write a "static library" that I was given a .c file?

Because that's where you write the executable code you want in the library. Header files consist of only function prototypes -- never (almost) executable code.

Thanks for the reply. I created a .lib file using VS '12. I sketched the following MASM code to test.

.model small
EXTRN printPrimes:PROC

.stack 100h

.data

.code

main proc
    mov dx, 2
    mov bx, 20

    call printPrimes

    mov ah, 04ch
    int 21h
main endp
end main

First of all, I have no idea how the assembler will know where to look for arguments of the printPrimes function. Second, while this code assembles, it isnt linking. I am giving the name of the library file and it says :

Fatal error primes.lib: Not a valid library

Could you help me troubleshoot this?

The contents of the library are below:

header.h:

#ifndef H1_H_INCLUDED
#define H1_H_INCLUDED

int isPrime(int number);

void printPrimes(int num1, int num2);

#endif // H1_H_INCLUDED

Prime.c:

#include "Header.h"

int isPrime(int a){
    int i = 0;
    for(i = 2; i<a; i++){
        if(a%i == 0){
            return 0;
        }
    }
}

void printPrimes(int a, int b){
    int i = 0;
    for(i = a; i<=b; i++){
        if(isPrime(i) == 1)
                printf("%d", i);
        //endif
    }
}

Fatal error primes.lib: Not a valid library

Now that I think about it I think MASM is a 16-bit assembler so it won't be able to read libraries compiled with 32/64 bit compilers. Either use a 16-bit compiler that produces *.lib files or use a 32-bit MASM assembler.

have no idea how the assembler will know where to look for arguments of the printPrimes

Your assembly code has to push them onto the stack before calling the function then remove them after the function returns. Parameters are pushed from right to left in the parameter list, so the second parameter is pushed first, then the first parameter is pushed second. This can be changed by changing the C calling convention.

.model small
EXTRN printPrimes:PROC

.stack 100h

.data

.code

main proc
    mov dx, 2
    mov bx, 20
    push dx ; second parameter
    push bx ; first parameter
    call printPrimes
    add sp,4 ; pop the two parameters from the stack

    mov ah, 04ch
    int 21h
main endp
end main

Now that I think about it I think MASM is a 16-bit assembler so it won't be able to read libraries compiled with 32/64 bit compilers.

To test that, I tried linking it with standard libraries in Masm615/LIB. It gave the same error for USER32.lib, KERNEL32.lib and IRVINE32.lib. It did not give the error for IRVINE16.lib. So I think you got that right. However, I can't help but think that the MASM I am using was provided by our Instructor; wouldnt he have considered the choice of assembler with the nature of assignments?

Anyway i am installing Masm32

Also, shouldn't it be
add sp, 8
?
Because we pushed two items on the stack...

Also, shouldn't it be
add sp, 8

No, because bx and dx are both 2-byte (16-bit) integers. ebx and edx are 32-bit (4 byte) integers.

MASM I am using was provided by our Instructor; wouldnt he have considered the choice of assembler

Maybe your instructor wants you to use a 16-bit C compiler. I don't know if Turbo C will produce the right *.lib files or not. MASM was produced by Microsoft in the 1980s to assemble MS-DOS 16-bit programs.

I generated a .lib using Turbo C++. Masm can read the library file atleast, however it seems to be unable to resolve the EXTRN. I'm pretty sure its a silly mistake on my part because i have been making quite a few along the way, but i'm sharing the code here:

Header.h:

#ifndef H1_H_INCLUDED
#define H1_H_INCLUDED

int isPrime(int number);

void printPrimes(int num1, int num2);

#endif // H1_H_INCLUDED

Prime.c:

#include <stdio.h>
#include "Header.h"

int isPrime(int a){
    int i = 0;
    for(i = 2; i<a; i++){
    if(a%i == 0){
        return 0;
    }//endif
    }
    return 1;
}

void printPrimes(int a, int b){
    int i = 0;
    for(i = a; i<=b; i++){
    if(isPrime(i) == 1)
        printf("%d", i);
    //endif
    }
}

main.asm

.model small
EXTRN printPrimes:PROC

.stack 100h

.data

.code

main proc
    mov dx, 2
    mov bx, 20

    push bx;
    push dx;

    call printPrimes
    add sp, 4

    mov ah, 04ch
    int 21h
main endp
end main

and the error:
error L2029: 'PRINTPRIMES' : Unresolved External

any ideas?

Did you also use the small memory model with Turbo C?

When you linked the assembled code did you tell the linker to also use the *.lib file along with the *.obj file geenrated by masm?

If you did all that then I suspect there are linking problems between masm (Microsoft) and Turbo C++ (Borland) object files. In that case you will need to replace MASM with TASM (Borland assembler)

Also, ask your instructor what compiler you are supposed to use with MASM. There is an old Microsoft C comiler, but AFAIK it is not free.

Did you also use the small memory model with Turbo C?

No, I was not aware we can do such a thing with Turbo. I am looking into this now

When you linked the assembled code did you tell the linker to also use the *.lib file along with the *.obj file geenrated by masm?

Yes I did. After entering the command
Link Main.obj
when i was prompted to enter any libraries, I entered the name of the library, which i had put in the same folder like "prime"

Well, turns out Turbo C was using small model by default :(
Also, our instructor is particular about using MASM for the course: initially I had been using FASM but he told me to switch to the former.

If it helps, I am on a 64-bit Windows 7, and I'm running this emulation of Turbo C++, which uses Dosbox.

Heres an update. I think i fixed the previous issue. I made two modifications in the process I was using and i dont know if it was one of them or the combination of the two:
1)I removed the preprocessor directives from the header file. I had a hunch that maybe they were causing the prototypes not to be read
2)A Tutorial had been telling me to use the instruction TLIB prime+prime.obj to link, however this time i used simply TLIB prime.

Currently the program is making DOSBox crash so i'll just do some quick debugging to confirm its working properly or not.

Right that was a false alarm. I hadnt linked it properly. After a couple of hours of work and research this is my new main.asm:

.model small


includelib Prime.lib
printPrimes PROTO C, :SDWORD, :SDWORD

.stack 100h

.data
arg1 SDWORD 2
arg2 SDWORD 20

.code

main proc
    mov cx, 20
    mov dx, 10

    invoke printPrimes, arg1, arg2 

    mov ah, 04ch
    int 21h
main endp
end main

In the

I dont really like the idea of using macros at this level of learning but there seems to be little other choice atm.

Now the problem is that when it links the .lib file, it seems to have a problem with the printf()

In my prime.c file, i have commented out the entire first procedure, and all instructions of the second procedure, and have just added a printf, like so:

#include <stdio.h>
#include "Header.h"

/*int isPrime(int num){
    int i = 0;
    for(i = 2; i<num; i++){
    if(num%i == 0){
        return 0;
    }//endif
    }
    return 1;
} */

void printPrimes(int a, int b){
   // int i = 0;
   /* for(i = a; i<=b; i++){
    if(isPrime(i) == 1)
        printf("%d", i);
    //endif
    }*/
    printf("I am working! A = %d  and B = %d", a, b);
}

The error now says :
_printf: unresolved external

Why why why? what was the point of including <stdio.h> in the C file? How complicated is it to make a C library for use with an assembly file? :(

Why why why?

Because you also have to link with standard C small libraries that are in Turbo C install folders.

In your assembly code you can delete lines 16 and 17 because those two registers are not being used by your program.

I completed my objective using inline assembly.

However this has got me thinking furiously about the role of libraries and headers.

For example, in "stdio.h", like one would expect from a header file, the prototype of printf is given, not the defination. So, in a C program, how is printf able to do what it does when there is no apparent defination of it? Is it somewhat automatic?

The actual executable code for printf is contained in a library. I don't know which one it is for Turbo C. You may have to link your assembly program with several standard C libraries because printf may call functions in other libraries, which in turn call more functions in some more libraries. When you write a plain C program the compiler already knows about all those libraries and produces the correct link statements for you. With MASM, and other assemblers, you are on your own.

If such complications arise for the process writing C libraries for use with MASM, I can only assume that the two were never intended to be mixed in such a way.

My instructor, however, maintains that there is a portability between C and Assembly, and can be used to solve complex problems in assembly ie: Writing tedious procedures in C, making a library out of them, then writing an assembly program that will use these procedures etc. This has left me confused.

If such complications arise for the process writing C libraries for use with MASM, I can only assume that the two were never intended to be mixed in such a way.

Incorrect. You just need to understand how all that fits together.

My instructor, however, maintains that there is a portability between C and Assembly,

He is correct. It's been my experience that you write the main part of the program in C and use assembly to optimize critical parts. That way let the C compiler figure out what all libraries has to be linked.

Thanks for your help throughout this thread :)

Oh and I dont know your exact age, but please try to live forever

Oh and I dont know your exact age, but please try to live forever

Happly that isn't going to happen :) I don't want to live forever, too much trouble.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.