Thread: linking to assembly

  1. #1
    Registered User
    Join Date
    Mar 2006
    Posts
    150

    linking to assembly

    Hello all! I am trying to link assembly code to my c application. I am using Dev-cpp with gcc, and my assembler is nasm. Here is the C code that i came up with:
    Code:
    #include <stdio.h>
    
    extern PrintHello (void);
    
    int main ()
    {
     char ch;
    
     ch = PrintHello ();
     printf ("%d", ch);
    }
    and here is the assembly code:

    Code:
    segment _CODE
    
    	global _PrintHello
    
    _PrintHello:
    
    	MOV AH,0x09
    	MOV DX,[msg]
    	INT 0x21
    
    	RET
    
    segment _DATA
    
     msg db "Hello!$"
    I tried to assemble the code into ELF object format, win32 object format, and coff format. The problem is the program just keeps crashing. It compiles fine with coff and ELF, but it wont run. Can anyone tell me how to assemble and link this code into my program? Sorry if this is an inappropriate post for this board, but i couldnt think of anywhere else to turn! Im kinda new at all this kind of stuff, so go easy on me

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    dev-c++ generates win32 console programs, and your asm uses a DOS interrupt.
    So yes, it's gonna blow up.

    Write the C equivalent of your asm, then do
    gcc -S prog.c
    on it, to see what it should look like.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Mar 2006
    Posts
    150
    So if i want to use interrupts, what can i do? I want to be able to use INT 16 for keyboard stuff. Is there a way to do that? Can i just tell Dev to make a DOS app somehow? Sry, dont know much about linking or the whole compilation process to be honest. yes, im gonna try and learn

  4. #4
    Ugly C Lover audinue's Avatar
    Join Date
    Jun 2008
    Location
    Indonesia
    Posts
    489
    xixpsychoxix:

    - After you generate elf e.g. data.o
    Just compile it with:
    Code:
    gcc your_c_code.c data.o
    - INT16 == short

    - I'm using MASM since 5 years ago...
    Btw xixpsychoxix, where do you learn ASM using NASM?
    It seems NASM generated code is cross platform. I've read the tutorial in PDF, but still a
    little bit confusing about its syntax.

    Thanks in advance.

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by xixpsychoxix View Post
    So if i want to use interrupts, what can i do? I want to be able to use INT 16 for keyboard stuff. Is there a way to do that? Can i just tell Dev to make a DOS app somehow? Sry, dont know much about linking or the whole compilation process to be honest. yes, im gonna try and learn
    If you want to use DOS interrupts, then you need to use a DOS compiler - such as Turbo C or Visual Studio 1.52 or earlier.

    gcc (which is the COMPILER used by Dev-CPP) can not generate 16-bit code whatsoever - you can make gas (the assembler that is used together with gcc) generate 16-bit code, but it's hard work, and only really supported to a minimal extent.

    I personally wouldn't spend effort trying to do any of that - it's obsolete by now, since there are nearly no systems actually using DOS as the base OS - yes, DOS functionality is still supported inside Windows, but it is emulated and translates into Windows system calls at some point or another. It would be a much better idea to learn how to use Windows system calls to perform what you want to do.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by audinue View Post
    xixpsychoxix:

    - After you generate elf e.g. data.o
    Just compile it with:
    Code:
    gcc your_c_code.c data.o
    - INT16 == short

    - I'm using MASM since 5 years ago...
    Btw xixpsychoxix, where do you learn ASM using NASM?
    It seems NASM generated code is cross platform. I've read the tutorial in PDF, but still a
    little bit confusing about its syntax.

    Thanks in advance.
    INT 16, however, is a interrupt to call BIOS on a PC - assuming of course that it's not running in a DOS-box on Windows or OS/2, in which case it's virtual interrupt that ends up in the OS itself, and then from there gets translated into the appropriate OS API call to perform the operation requested.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Registered User
    Join Date
    Mar 2006
    Posts
    150
    Does anyone know where i can find a compiler that will produce a flat binary image? I want to mess around with writing a small OS kernel but since gcc is only win32, that wont work... how about digital mars? does that one do binary images? i guess i could read the documentation, but if anyone knows of a good compiler that will do what im looking for, please let me know.

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by xixpsychoxix View Post
    Does anyone know where i can find a compiler that will produce a flat binary image? I want to mess around with writing a small OS kernel but since gcc is only win32, that wont work... how about digital mars? does that one do binary images? i guess i could read the documentation, but if anyone knows of a good compiler that will do what im looking for, please let me know.
    gcc + helper tools is able to produce Linux binaries, so I don't see why it wouldn't be able to produce one under Windows [in fact, I have used gcc under Linux to produce "basic" binaries to test virtualization too - and I expect those tools to be available under Windows gcc-mingw package too].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    The digital mars website mentions 16-bit, so perhaps it could be used.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  10. #10
    Registered User
    Join Date
    Mar 2006
    Posts
    150
    So if i made a 16-bit DOS binary, that would suffice, right? Or do i have to do anything more to it to use a boot loader to load it? So i guess what im asking is what do i have to do to a DOS binary to be able to load it using a bootloader and run it without DOS? What is the difference between .com and .bin format?
    Last edited by xixpsychoxix; 07-15-2008 at 08:47 PM.

  11. #11
    Registered User
    Join Date
    Mar 2006
    Posts
    150
    Ok, so im having my compiler generate a 16-bit DOS binary just to test my stuff out... here is the code i have to print a line:

    Code:
    _print_string proc near
    
    	PUSH BP
    
    	MOV BP,SP
    
    	MOV AH,09h
    	MOV DX,OFFSET [BP+4]
    	INT 21h
    
    	POP BP
    
    	RETN
    
    _print_string endp
    This code keeps crashing my program, but i cant see why. I am trying to store the address of the string from the stack into dx and print it with int 21. can anyone help me with getting C pointers from the stack and using them?

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by xixpsychoxix View Post
    Ok, so im having my compiler generate a 16-bit DOS binary just to test my stuff out... here is the code i have to print a line:

    Code:
    _print_string proc near
    
    	PUSH BP
    
    	MOV BP,SP
    
    	MOV AH,09h
    	MOV DX,OFFSET [BP+4]
    	INT 21h
    
    	POP BP
    
    	RETN
    
    _print_string endp
    This code keeps crashing my program, but i cant see why. I am trying to store the address of the string from the stack into dx and print it with int 21. can anyone help me with getting C pointers from the stack and using them?
    First of all, the OFFSET [BP+4] doesn't even make sense. It should probably be WORD PTR [BP+4] - the assembler may well do the right thing, but having it right would definitely help matters.

    Second, the INT 21h would expect the string at DSX, so is DS set to the right value for your string?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #13
    Registered User
    Join Date
    Mar 2006
    Posts
    150
    How can i make sure that DS is set to the right value? The problem is im not quite sure how C pushes addresses onto the stack

  14. #14
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by xixpsychoxix View Post
    How can i make sure that DS is set to the right value? The problem is im not quite sure how C pushes addresses onto the stack
    I'm not sure how you are calling the function, so I don't quite know what you can expect either - that is one of the complications of writing assembler that interfaces with (for example) C - you need to understand the parameter passing mechanism to understand what you need to do. Most likely, you could do:
    Code:
    lds dx, dword ptr [bp+4]
    but I could very well be wrong.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  15. #15
    Registered User
    Join Date
    Mar 2006
    Posts
    150
    Ok, here is the entire source for both of the programs:

    ASM:
    Code:
    .486
    .MODEL small
    .CODE
    
    	PUBLIC _read_char
    	PUBLIC _write_char
    	PUBLIC _print_string
    
    _read_char proc near
    
    	MOV AH,0h
    	INT 16h
    
    	RETN
    
    _read_char endp
    
    _write_char proc near
    
    	PUSH BP
    
    	MOV BP,SP
    	MOV DL,BYTE [BP+4]
    	
    	MOV AH,02h
    	INT 21h
    
    	RETN
    
    _write_char endp
    
    _print_string proc near
    
    	PUSH BP
    
    	MOV BP,SP
    
    	MOV AH,09h
    	LDS DX,DWORD PTR [BP+4]
    	INT 21h
    
    	POP BP
    
    	RETN
    
    _print_string endp
    
    END
    C:
    Code:
    extern int read_char (void);
    extern void write_char (char);
    extern void print_string (char *);
    
    int main ()
    {
     char *line = "Hello, world!";
    
     print_string (line);
     return 0;
    }
    I get no compiler errors or assembler errors, but when i run the program, I get a message saying that the CPU detected an illegal instruction!!! This is really frustrating

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Linking C++ and Assembly
    By Warlax in forum C++ Programming
    Replies: 6
    Last Post: 10-19-2007, 04:33 PM
  2. HELP: assembly & C linking woes....
    By andrewwan1980 in forum Tech Board
    Replies: 4
    Last Post: 09-28-2007, 04:17 PM
  3. True ASM vs. Fake ASM ????
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 7
    Last Post: 04-02-2003, 04:28 AM
  4. Linking an assembly routine into a GCC project
    By huh in forum C++ Programming
    Replies: 3
    Last Post: 11-21-2002, 03:14 PM
  5. C,C++,Perl,Java
    By brusli in forum C Programming
    Replies: 9
    Last Post: 12-31-2001, 03:35 AM