Category : Files from Magazines
Archive   : DDJ0892.ZIP
Filename : ASM_2_C.ASC
Output of file : ASM_2_C.ASC contained in archive : DDJ0892.ZIP
by Beth Mazur
[LISTING ONE}
; 1 /* Here is a method of determining how the compiler expects parameters
; 2 to be passed between C and assembly routines. For example, suppose
; 3 you need to pass 3 integers to an assembly routine, where they will
; 4 be manipulated, and an integer value returned. The trick is to write
; 5 a C routine that simulates this. Then compile to assembly and see how
; 6 the compiler treats the parameters (you can use the generated
; 7 assembly code as a template and add your code to it). */
; 8 int h,i,j,k;
; 9 main()
; 10 {
_main:
; 11 h = subroutine(i,j,k);
ldd _k ; push k on stack first
pshd
ldd _j ; push j on stack next
pshd
ldd _i ; leave i in register
jbsr _subroutine
ins ; clear parameters off stack
ins
ins
ins
std _h ; result in register
; 12 }
rts
; 13 int subroutine(int a, int b, int c)
; 14 {
_subroutine:
pshx ; save X
pshd ; save i on stack
tsx ; transfer SP to X
.set OFST=0
; 15 return(a+b+c);
ldd OFST+0,x ; code to copy i back to D
addd OFST+6,x ; add j
addd OFST+8,x ; add k, result left in D
pulx ; restore D into X from stack
pulx ; restore X
rts
; 16 }
[LISTING TWO]
extern void reset(); /* symbol defined in startup routine */
extern void default(); /* generic routine generates a return from interrupt */
void (* const vec_tab[])() = {
default, /* SCI */
default, /* SPI */
default, /* Pulse accumulator input edge */
default, /* Pulse accumulator overflow */
default, /* Timer overflow */
default, /* Timer output compare 5 */
default, /* Timer output compare 4 */
default, /* Timer output compare 3 */
default, /* Timer output compare 2 */
default, /* Timer output compare 1 */
default, /* Timer input capture 3 */
default, /* Timer input capture 2 */
default, /* Timer input capture 1 */
default, /* Real time interrupt */
default, /* IRQ */
default, /* XIRQ */
default, /* SWI */
default, /* illegal op-code */
default, /* COP watchdog timer fail */
default, /* COP monitor clock fail */
reset, /* RESET */
};
[LISTING THREE]
; 1 /* Here is a method of accessing the M68HC11 I/O ports that is portable
; 2 and can be compiled by most C compilers. c is declared as an int
; 3 because that's how putchar is defined by ANSI. The (char) cast is done
; 4 to avoid "illegal assignment" warnings from strict compilers. */
; 5 #define SCSR *(char *) 0x102e /* SCI Status Register */
; 6 #define SCDR *(char *) 0x102f /* SCI Data Register */
; 7 #define TDRE 0x80 /* Transmit Data Register Empty bit */
; 8 int putchar(int c)
; 9 {
_putchar:
pshx
pshd
tsx
.set OFST=0
L1: ; line 14, offset 3
; 10 while (!(SCSR & TDRE))
ldab 102eH
bitb #128
beq L1
; 11 /* loop until ready to transmit */
; 12 SCDR = (char) c;
ldab OFST+1,x
stab 102fH
; 13 return(c);
ldd OFST+0,x
pulx
pulx
rts
; 14 }
.public _putchar
.end
Example 1:
int factorial(int fact)
{
int temp;
temp=fact;
if (!fact)
temp=1; /* fact = 0? */
else
temp*=factorial(temp-1); /* fact > 0 */
return (temp);
}
Example 2:
(a)
const double pi = 3.14159;
main()
{
pi = 1.234; /* will generate error at compile-time */
}
(b)
extern const double pi;
double circum(double radius)
{
double circ;
circ = 2.0 * pi * radius;
}
Example 3:
; 1 volatile char porta;
; 2 char portb;
; 3 test()
; 4 {
_test:
; 5 porta=1;
ldab #1
stab _porta
LL4:
; 6 porta=2;
ldab #2
stab _porta
LL6:
; 7 portb=1; /* optimized out as redundant */
; 8 portb=2;
ldab #2
stab _portb
; 9 }
rts
; 10
Example 4:
/* Initialized variables are declared with a value. The variable will have
this value when the program begins executing. Uninitialized variables are
not declared with a value. */
int days_of_year = 365; /* this is an intialized variable */
int number_of_days; /* this is uninitialized */
Example 5:
long a,b;
int i,j,k;
int subroutine(int first, long second);
main()
{
i=subroutine(j,a); /* no action will be taken */
i=subroutine(j,k); /* compiler will promote k to long */
i=subroutine(a,b); /* will generate error, since long
cannot be passed for first param */
}
Example 6:
#define RDRF 0x20 /* Receive Data Register Full */
#define TRDE 0x80 /* Transmit Data Ready Empty */
#define SCSR *(char *) 0x102e /* SCI Status Register */
#define SCDR *(char *) 0x102f /* SCI Data Register */
int putchar(int c)
{
if (c == '\n')
putchar('\r'); /* put newline and carriage return */
while (!(SCSR & TRDE)) /* wait until ready to receive */
;
SCDR = c; /* output character */
return (c);
}
int getchar()
{
int c;
while (!(SCSR & RDRF)) /* wait for character */
;
c = SCDR; /* receive character */
if (c == '\r')
c = '\n'; /* translate to newline */
return (c);
}
Example 7:
(a)
i = 1; /* i is declared as an int */
(b)
ldab #1
stab _i
(c)
jsr _func
Example 8:
main()
{
...
_asm("sei\n"); /* disable interrupts */
func(); /* call function */
_asm("cli\n"); /* enable interrupts */
...
}
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/