CompuServe Messages

Setjmp/longjmp

#: 1532 S9/Software DevelopersForum unknown
    12-Dec-85 10:51:57
Sb: Setjmp/longjmp
Fm: GARY SARFF 70167,2216
To: John Foust 72237,135

This message turned up in search, but its forum couldn’t be identified from the original transcript, so it may not be linked into its thread.

Here is the code for setjmp and longjmp that you had to rip out of your program. Do you have the macro assembler? If not I can assemble them and upload the .o files so they will be linkable. In the C program: have typedef int jmp_buf[13]; call with: setjmp(environ); where environ is declared as a jmp_buf; and longjmp(environ,value); value is the value to be returned to the caller of setjmp. An integer; Assembler: RORG 0 XDEF _setjmp XDEF _longjmp _setjmp: movea.l (sp)+,a1 movea.l (sp),a0 movem.l sp-a1/d7-d2,(a0) moveq.l #0,d0 jmp (a1) _longjmp: movea.l 4(sp),a0 move.l 8(sp),d0 movem.l (a0),sp-a1/d7-d2 jmp (a1) END That's it. Just assemble and link with the C code. The code for alarm() wouldn't be much use because it traps into unix kernel code. someone will have to come up with something else, an amiga anology. GARY Functions: B – bulletins CO – conference D – delete DL – data libraries E – exit G x- go to page x I – instructions L – leave a message M – previous menu MI – membership information NEW- new/changes OFF- log off OP – set options QS – quick scan R – read messages R x- run SIG x RT – read thread S – scan headers SD – scan & display SEN- send a message SN – sub-topic names SS – set sub-topic T – go DISPLA U – user log UST- current users V – interests X – database ? x – explanation of function x [70003,2443] QSORT.ASM 12-Dec-85 8800 4 Keywords: ASSEMBLER UNIX QSORT An implementation of the Unix ™ qsort() facility callable from assembler or C. See QTEST.C for an example of how to use this. This file was provided by Gary Sarff. (R D T): rea RORG 0 XDEF _qsort * The qsort algorithm implemented in 68000 assembler. * This routine implements the quick sort for any arbitrary data array of * any arbitrary size. The sort is "in-place" in the array, no temporary * space is needed aside from a little stack space. I have tried to keep * this as close to the Unix conventions of qsort as possible. I don't * think there are any bugs, but who knows. * Gary Sarff 12/07/85 Compuserve PPN 70167,2216 * * Calling convention/declaration from Lattice C programs is: * * void qsort((char *)base,nel,sizeof (*base),compar) * unsigned int nel; * int (*compar)(); * * base points to the base element of the table to be sorted. * nel is the number of elements in the table. * compar is the name of the comparison function, which is called with two * arguments that point to the elements being compared. The function * must return an integer less than, equal to, or greater than zero * according as the first argument is to be considered less than, equal to, * or greater than the second. * for example: * suppose array is declared as: * struct junk { int xpart; * int ypart; * char *message[20]; * } *array[10]; * Then array points to the first of ten identical structures like junk. * say if we want to sort the array on the xpart then call qsort like: * qsort((char *)array,10,sizeof(*array),compar); * you should find sizeof(*array) to be 24 since array is a pointer to * something of type junk and each thing is 24 bytes long. * * Notes: The pointer to the base table should be of type * pointer-to-element, and cast to type pointer-to-character. The comparison * function need not compare every byte, so arbitrary data may be contained in * the elements in addition to the values being compared. In this case only * compare the xparts of the two values passed (see below). * Although declared as pointer-to-character, the value returned should be * cast into type pointer-to-element. * * the compar function should be declared as (of course use any name you * want as long as you pass the name to qsort.) * * int compar(first,second) * and declare first and second as type pointer-to-element. They must be * declared this way, not as pointer to char or something else, so then you * can say: * if (first->xpart < second->xpart) return (-1); * if (first->xpart == second->xpart) return 0; * if (first->xpart > second->xpart) return 1; * *————————————————————————– * _qsort: link a6,#-4 move.l 20(a6),cmpaddr move.l 16(a6),nel move.l 16(a6),(sp) move.l 12(a6),-(sp) bsr.l unsgmul * multiply nel by sizeof elements addq.l #4,sp add.l 8(a6),d0 move.l d0,(sp) move.l 8(a6),-(sp) bsr.s qcont unlk a6 rts qcont: link a6,#-4 movem.l d0/d5-d7/a2/a4-a5,-(sp) move.l nel,d7 QL0: move.l 12(a6),d0 sub.l 8(a6),d0 move.l d0,d5 cmp.l d7,d0 bls.l done1 move.l d7,d0 add.l d0,d0 move.l d0,(sp) move.l d5,-(sp) bsr.l unsgdiv addq.l #4,sp move.l d0,(sp) move.l d7,-(sp) bsr.l unsgmul addq.l #4,sp move.l d0,d5 move.l 8(a6),d0 add.l d5,d0 movea.l d0,a2 move.l a2,-4(a6) movea.l 8(a6),a5 move.l 12(a6),d0 sub.l d7,d0 movea.l d0,a4 bra.s compout comploop: suba.l d7,a2 move.l a2,(sp) move.l a5,-(sp) bsr.l auxfunc addq.l #4,sp bra.s compout complt: move.l a2,(sp) move.l a5,-(sp) movea.l cmpaddr,a0 jsr (a0) * call the user provided compar function addq.l #4,sp move.l d0,d6 beq.s comploop tst.l d6 bge.s compge QL1: adda.l d7,a5 compout: cmpa.l a2,a5 bcs.s complt bra.s compge move.l a4,(sp) add.l d7,-4(a6) move.l -4(a6),-(sp) bsr.l auxfunc addq.l #4,sp bra.s compge qloop1: move.l a4,(sp) add.l d7,-4(a6) move.l -4(a6),-(sp) move.l a5,-(sp) bsr.l qdone addq.l #8,sp adda.l d7,a2 movea.l a2,a5 bra.s compge QL2: move.l a4,(sp) move.l -4(a6),-(sp) movea.l cmpaddr,a0 jsr (a0) addq.l #4,sp move.l d0,d6 beq.s compout tst.l d6 ble.s seege cmpa.l a2,a5 beq.s qloop1 * see if we have reached end of table move.l a4,(sp) move.l a5,-(sp) bsr.l auxfunc addq.l #4,sp suba.l d7,a4 bra.s QL1 seege: suba.l d7,a4 compge: cmpa.l -4(a6),a4 bhi.s QL2 cmpa.l a2,a5 bne QL3 move.l a2,d0 sub.l 8(a6),d0 move.l 12(a6),d1 sub.l -4(a6),d1 cmp.l d1,d0 blt.s QL4 move.l 12(a6),(sp) move.l -4(a6),d0 add.l d7,d0 move.l d0,-(sp) bsr.l qcont * recursive call with partition of table addq.l #4,sp move.l a2,12(a6) bra.l QL0 QL4: move.l a2,(sp) move.l 8(a6),-(sp) bsr.l qcont * recursive call with rest of table. addq.l #4,sp move.l -4(a6),d0 add.l d7,d0 move.l d0,8(a6) bra.l QL0 QL3: move.l a5,(sp) suba.l d7,a2 move.l a2,-(sp) move.l a4,-(sp) bsr.s qdone addq.l #8,sp sub.l d7,-4(a6) movea.l -4(a6),a4 bra.l compout done1: addq.l #4,sp movem.l (sp)+,a5-a4/a2/d7-d5 unlk a6 rts auxfunc: link a6,#0 movem.l d6-d7/a4-a5,-(sp) move.l nel,d6 movea.l 8(a6),a5 movea.l 12(a6),a4 moveloop: move.b (a5),d7 move.b (a4),(a5)+ move.b d7,(a4)+ subq.l #1,d6 bne.s moveloop movem.l (sp)+,a5-a4/d7-d6 unlk a6 rts qdone: link a6,#0 movem.l d6-d7/a3-a5,-(sp) move.l nel,d6 movea.l 8(a6),a5 movea.l 12(a6),a4 movea.l 16(a6),a3 pivloop: move.b (a5),d0 ext.w d0 ext.l d0 move.l d0,d7 move.b (a3),(a5)+ move.b (a4),(a3)+ move.b d7,(a4)+ subq.l #1,d6 bne.s pivloop movem.l (sp)+,a5-a3/d7-d6 unlk a6 rts CNOP 0,4 cmpaddr: DC.L 0 nel: DC.L 0 * * support routines to do unsigned multiplication and division * unsgmul: lea 4(sp),a0 move.w (a0)+,d0 move.l 8(sp),d1 mulu d1,d0 swap d1 mulu (a0),d1 add.w d1,d0 swap d0 clr.w d0 move.w (a0),d1 mulu 10(sp),d1 add.l d1,d0 move.l d0,-2(a0) rts unsgdiv: lea 4(sp),a0 movem.l d2-d3,-(sp) move.l (a0),d0 move.l d0,d2 move.l 16(sp),d1 move.l d1,d3 cmpi.l #$10000,d1 bge.s adjust clr.w d0 swap d0 divu d1,d0 move.w d0,d3 move.w d2,d0 divu d1,d0 swap d0 move.w d3,d0 swap d0 bra.s fini adjust: lsr.l #1,d0 lsr.l #1,d1 cmpi.l #$10000,d1 bge.s adjust divu d1,d0 andi.l #$FFFF,d0 move.l d3,d1 swap d1 mulu d0,d1 swap d1 clr.w d1 mulu d0,d3 add.l d3,d1 cmp.l d1,d2 bge.s fini subq.l #1,d0 fini: move.l d0,(a0) movem.l (sp)+,d3-d2 rts [70003,2443] QTEST.C 12-Dec-85 1300 3 Keywords: QTEST C This is a test program to demonstrate the use of QSORT.ASM. Provided by Gary Sarff. (R D T): rea /* A program to test the qsort "quick-sort" procedure called from Lattice Gary Sarff 12/07/85 Compuserve PPN: 70167,2216 Compile this program with something similar to copy qtest.c to ram: copy qsort.o to ram: :c/lc1 -i:include/ -i:include/lattice/ ram:qtest :c/lc2 ram:qtest :c/alink :lib/lstartup.obj,ram:test.o,ram:qsort.o library :lib/lc.lib,:lib/amiga.lib to ram:test map nil: when you run qtest it should produce 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 Sorting… Finished 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */ #include <stdio.h> extern qsort(); int array[] = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0}; /* test array */ int compfunc(first,second) int *second,*first; { if ((*first) < (*second)) return(-1); else if ((*first) == (*second)) return 0; else if ((*first) > (*second)) return 1; } main() { int i; unsigned int arsize; arsize=sizeof(array)/sizeof(int); for (i=0;i < arsize; i++) printf("%d ",array[i]); printf("\nSorting…\n"); qsort(&array[0],arsize,sizeof(int),compfunc); printf("finished\n"); for (i=0;i < arsize; i++) printf("%d ",array[i]); printf("\n"); }