1) May be this will help: http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html. Literal constants are prefixed by $ and hex values are prefixed 0x just as in C/C++. So $0x0 (although $0 will suffice since zero is zero regardless of radix). The strange thiung is you used $0x21 in your second example, so you must have already known that!?
2) Int 0x21 is an MS-DOS system call. Unless you have replaced the default MinGW/GCC compiler with the 16bit DJPP compiler you cannot use Dev-C++ to write 16-bit code. Besides, there is no advantage in attempting to call the 16-Bit compatibility subsystem, since Windows virtualises all such calls - trapping them with a handler than emulates DOS. It has to do that because in reality, even in console mode(other than full-screen mode), text strings are rendered graphically using Window's fonts, and 'drawn' on teh screen rather than placing a single byte in the Video RAM. So there is no real advantage in attempting to render a string via a DOS call. I would bet that it will in fact be far slower than using Win32 console API calles, or even stdio/iostream calls. I can think of few reasons why you would want to do that when the WIn32 system calls provide a far richer and more powerful range of services. This is 2009 not 1989!
User mode Win32 applications cannot invoke software interrupts (among other restrictions). This is necessary for system integrity. Unlike MS-DOS, Windows executes multiple programs concurrently - they have to abide by the rules and cannot claim system level resources for themselves - this is brokered by the OS and kernel level drivers.
3) See the link I posted at (1).
Note that on a modern processor with a modern OS, there are few justifiable reasons for using assembler. If you think you have a good reason, consider carefully:
Use system provided services in preference to any attemptto directly access hardware or I/O.
If you think that you need assembler for performance reasons, consider that the compiler optimiser is an 'expert-system'. It contains knowledge of the target architecture that will take you a very long time to master. Are you aware for example of how to take best advantage of branch prediction, instruction pipelining, and instruction/data caching. Do you know every instruction on teh processor, including extensions such as MMX SSE, etc?. Also the compiler takes a holistic view of code, and will perform optimisations over large spans of code for the greater benefit of the whole. Most human assembler programmers can only work on the small scale (the compiler does that too), and sweating the small stuff is not very productive.
If you have not measured the performance of a non-assembler implementation, and do not have well defined requirements regarding performance, then you have nothing by which to measure your efforts to determine whether it was worthwhile.
If you want to use assembler to access some feature not available to high-level code, then it is likely that that feature is protected by the OS and that you will need a kernel level driver to make it work.
If you merely want to port some old DOS code, change it to use Win32 OS services rather than DOS emulation.
Clifford
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi,
My environment is as follows:
Win XP Prof SP3
Dev C++ 4.9.9.2 in C:\Dev-Cpp5\
I've 3 matters using 8086 assembler code:
1. How can I use constant values?
I post here the code:
include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
asm ("push %ax");
asm ("mov %ax, 0h");
__asm ("pop %ax");
}
Now, I post here the FULL log:
Compilador: Default compiler
Ejecutando g++.exe...
g++.exe "C:\Dev-Cpp5\CursoCpp\Futuro\ASM\ej_ctes.cpp" -o "C:\Dev-Cpp5\CursoCpp\Futuro\ASM\ej_ctes.exe" -g3
-I"C:\Dev-Cpp5\lib\gcc\mingw32\3.4.2\include" -I"C:\Dev-Cpp5\include\c++\3.4.2\backward"
-I"C:\Dev-Cpp5\include\c++\3.4.2\mingw32" -I"C:\Dev-Cpp5\include\c++\3.4.2" -I"C:\Dev-Cpp5\include"
-L"C:\Dev-Cpp5\lib" -g3
C:\DOCUME~1\JOSEMA~1\CONFIG~1\Temp/ccILaaaa.s: Assembler messages:
C:\DOCUME~1\JOSEMA~1\CONFIG~1\Temp/ccILaaaa.s:526: Error: junk `h' after expressionEjecución Terminada
2. Can I use interruptions in Dev-Cpp?
I post here the code:
include <iostream>
using namespace std;
const char* MyString = "Hello, world...";
int main(int argc, char *argv[])
{
asm("pusha");
asm("movb $9, %ah");
asm("movw _MyString, %dx");
asm("int $0x21");
__asm("popa");
system("PAUSE");
return 0;
}
I can compile it, but when I arrive to the "int $0x21" instruction, I get something like "A memory access violation
(segmentation fault) has happend in your program".
How can I do a "Hello world" program?
3. How can I export values from 8086 to DevC++?
I've written a code that asks 2 numbers and performs n1+n2, and returns it.
I post here the code:
include <iostream>
using namespace std;
int number1, number2, result;
int main(int argc, char *argv[])
{
printf("n1: ");
scanf("%d", &number1);
printf("\n n2: ");
scanf("%d", &number2);
}
I can compile and execute it, but the value that is in "result" always is 0.
Am I exporting the value of "result" properly?
Thank you very much.
Side note - keeping your code in your Dev directory is a bad idea.
Wayne
1) May be this will help: http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html. Literal constants are prefixed by $ and hex values are prefixed 0x just as in C/C++. So $0x0 (although $0 will suffice since zero is zero regardless of radix). The strange thiung is you used $0x21 in your second example, so you must have already known that!?
2) Int 0x21 is an MS-DOS system call. Unless you have replaced the default MinGW/GCC compiler with the 16bit DJPP compiler you cannot use Dev-C++ to write 16-bit code. Besides, there is no advantage in attempting to call the 16-Bit compatibility subsystem, since Windows virtualises all such calls - trapping them with a handler than emulates DOS. It has to do that because in reality, even in console mode(other than full-screen mode), text strings are rendered graphically using Window's fonts, and 'drawn' on teh screen rather than placing a single byte in the Video RAM. So there is no real advantage in attempting to render a string via a DOS call. I would bet that it will in fact be far slower than using Win32 console API calles, or even stdio/iostream calls. I can think of few reasons why you would want to do that when the WIn32 system calls provide a far richer and more powerful range of services. This is 2009 not 1989!
User mode Win32 applications cannot invoke software interrupts (among other restrictions). This is necessary for system integrity. Unlike MS-DOS, Windows executes multiple programs concurrently - they have to abide by the rules and cannot claim system level resources for themselves - this is brokered by the OS and kernel level drivers.
3) See the link I posted at (1).
Note that on a modern processor with a modern OS, there are few justifiable reasons for using assembler. If you think you have a good reason, consider carefully:
Use system provided services in preference to any attemptto directly access hardware or I/O.
If you think that you need assembler for performance reasons, consider that the compiler optimiser is an 'expert-system'. It contains knowledge of the target architecture that will take you a very long time to master. Are you aware for example of how to take best advantage of branch prediction, instruction pipelining, and instruction/data caching. Do you know every instruction on teh processor, including extensions such as MMX SSE, etc?. Also the compiler takes a holistic view of code, and will perform optimisations over large spans of code for the greater benefit of the whole. Most human assembler programmers can only work on the small scale (the compiler does that too), and sweating the small stuff is not very productive.
If you have not measured the performance of a non-assembler implementation, and do not have well defined requirements regarding performance, then you have nothing by which to measure your efforts to determine whether it was worthwhile.
If you want to use assembler to access some feature not available to high-level code, then it is likely that that feature is protected by the OS and that you will need a kernel level driver to make it work.
If you merely want to port some old DOS code, change it to use Win32 OS services rather than DOS emulation.
Clifford