gp@picuxa.UUCP (Greg Pasquariello X1190) (10/08/87)
I ran into a small problem today, and I was wondering if anyone could shed some light on it. I wrote a test program in MSC 4.0 that will set up an interrupt handler for the clock interrupt (0x1C). The interrupt handler itself was a small ASM module that simply printed out stars whenever the interrupt occured. Fine. The next thing I did was change the int handler to increment a word of memory (a variable) rather than print stars, and when the interrupt was done being serviced, the C program printed the value of the variable. Problem was, the value was ALWAYS 0. I then ran the interrupt handler and the C code (a single, small model program) through Codeview, and found that the variable *WAS* being incremented. Now can anyone tell me why the variable is incremented when the routine is used as a called function, but not when the routine is used as an interrupt routine? The MSC routines are compiled using the small memory model option, and the ASM routine is set up to be compatible with the C code (_TEXT segment, _DATA segment, DGROUP, and all that). All publics are declared within the ASM module, and properly begin with an '_'. The code is linked as one program with the interrupt handler embedded, and the routine that sets up the new interrupt vector does so correctly. Any help will be appreciated. Thanks in advance. BTW: Thanks to all who responded to my question about the "hole" in the stack. The answer dawned on me just after I posted the question! Greg Pasquariello
jru@etn-rad.UUCP (John Unekis) (10/09/87)
In article <330@picuxa.UUCP> gp@picuxa.UUCP (Greg Pasquariello X1190) writes: >I ran into a small problem today, and I was wondering if anyone could >shed some light on it. I wrote a test program in MSC 4.0 that will ... >tell me why the variable is incremented when the routine is used as a called >function, but not when the routine is used as an interrupt routine? Remember that addresses on the intel processor are composed of two parts, a segment, which comes from one of the segment registers, and an offset which may be a register or part of the instruction. When you use the small model compiler it is assumed that all of your data fits in one segment, and the data segment(DS) register is loaded once at the start of your program and never changed. When you call your routine as a subroutine, the data segment register is properly set up, and your routine accesses the increment variable location as an offset from the DS register. When you come into your routine off an interrupt, the data segment is set up to whatever DOS left it at before jumping to your routine. When you try to increment your variable as an offset from the data segment you are actually incrementing some location in the DOS data space(bad idea). In order to find the variable that you really want to increment, you will have to have a separate entry point to your routine that will save the user mode data segment register in a memory loacation in the code portion of your interrupt service routine. Then when you catch an interrupt, you should push the DS on the stack, retreive the user mode DS from the location in your code segment, increment your variable at the correct location, then pop the DOS mode DS back off the stack. BTW: This is why Motorola 680X0 processors are so popular for real - time applications that require interrupt handling and data sharing, NO SEGMENTS. An address is an address is an address. The propagation of this archaic segmented architecture into Intel's state-of-the-art 80X86 chips in order to preserve IBM PC compatibility reminds me of an old joke: Intel to IBM : Mommy, Mommy, why do I keep walking in circles? IBM to Intel : Shut up or I'll nail your other foot to the floor.
daveb@laidbak.UUCP (Dave Burton) (10/09/87)
In article <330@picuxa.UUCP> gp@picuxa.UUCP (Greg Pasquariello X1190) writes: >... >I wrote a test program in MSC 4.0 that will >set up an interrupt handler for the clock interrupt (0x1C). >... >The next thing I did was change the int >handler to increment a word of memory (a variable) rather than print stars, >and when the interrupt was done being serviced, the C program printed the >value of the variable. Problem was, the value was ALWAYS 0. I then ran >the interrupt handler and the C code (a single, small model program) through >Codeview, and found that the variable *WAS* being incremented. Now can anyone >tell me why the variable is incremented when the routine is used as a called >function, but not when the routine is used as an interrupt routine? >... (venturing to speak without the manuals handy...) The way you have described the problem, your variable is not being referenced properly ONLY when called by the interrupt router. I believe (95% sure) that SS is changed when the interrupt is first serviced. If you wish to access any variables from your C program, you must retrieve the SS pointer from the stack, then add the variable's offset to it. A good book to read which addresses this subject is "Supercharging C with Assembly". It is 100% PC/MSDOS specific, but if you're unfortunate enough to be stuck there, this book gives decent advice and examples. -- --------------------"Well, it looked good when I wrote it"--------------------- Verbal: Dave Burton Net: ...!ihnp4!laidbak!daveb V-MAIL: (312) 505-9100 x325 USSnail: 1901 N. Naper Blvd. #include <disclaimer.h> Naperville, IL 60540
flaps@utcsri.UUCP (10/16/87)
gp@picuxa.UUCP (Greg Pasquariello X1190) writes, slightly edited by ajr: >I wrote a test program in MSC 4.0 [on the ibm-pc] that will >set up an interrupt handler... >The next thing I did was change the int >handler to increment a word of memory (a variable), >and when the interrupt was done being serviced, the C program printed the >value of the variable. Problem was, the value was ALWAYS 0. I then ran >the interrupt handler and the C code through >[a symbolic debugger], and found that the variable *WAS* being incremented. This may or may not be your problem, but you should be declaring this variable to be volatile. Otherwise, the compiler is free to compile something like the printf in: function() { static int i = 8; ... [no statements affecting the value of i] printf("%d\n",i); ... [no more statements affecting the value of i, or getting any pointers to it] } as: printf("%d\n",8); If you add in a 'volatile', the compiler is required to generate code which actually fetches the value every time you tell it to. ajr