Assembler with LCC-Win32

The routines below do a mem_set for longs, words and bytes plus an add to array with value for longs, words and bytes. The instructions lods (load string) and stos (store string) are used.

For the add routines both ESI and EDI are used - lods uses ESI and stos uses EDI

For the set routines only EDI is used for stos

MemSuff

#include <stdio.h>

// protos
void add_arrl(int * arr, int i, size_t n);
void mem_setl(int * arr, int i, size_t n);

void add_arrw(short * arr, short i, size_t n);
void mem_setw(short * arr, short i, size_t n);

void add_arrb(char * arr, char i, size_t n);
void mem_setb(char * arr, char i, size_t n);

void __declspec(naked) add_arrl(int * arr, int i, size_t n)
{
    _asm("pushl %esi");         // save register
    _asm("pushl %edi");         // save register
    _asm("movl 12(%esp),%edi"); // get array address in edi
    _asm("movl %edi,%esi");     // get array address in esi
    _asm("movl 16(%esp),%edx"); // the value in edx
    _asm("movl 20(%esp),%ecx"); // the number of array elements
    _asm("cmpl $0,%ecx");
    _asm("jle exit1");          // bail out if zero or less
    _asm("cld");                // ESI and EDI are incremented
_asm("start1:");
    _asm("lodsl");              // get current array element into EAX
    _asm("addl %edx,%eax");     // add value
    _asm("stosl");              // put it back into the array
    _asm("loop start1");        // loop until (ECX==0)
_asm("exit1:");
    _asm("popl %edi");
    _asm("popl %esi");
    _asm("ret");
}

void __declspec(naked) add_arrw(short * arr, short i, size_t n)
{
    _asm("pushl %esi");
    _asm("pushl %edi");
    _asm("movl 12(%esp),%edi");
    _asm("movl %edi,%esi");
    _asm("movl 16(%esp),%dx");    // the value in dx
    _asm("movl 20(%esp),%ecx");
    _asm("cmpl $0,%ecx");
    _asm("jle exit2");
    _asm("cld");
_asm("start2:");
    _asm("lodsw");
    _asm("addw %dx,%ax");
    _asm("stosw");
    _asm("loop start2");
_asm("exit2:");
    _asm("popl %edi");
    _asm("popl %esi");
    _asm("ret");
}

void __declspec(naked) add_arrb(char * arr, char i, size_t n)
{
    _asm("pushl %esi");
    _asm("pushl %edi");
    _asm("movl 12(%esp),%edi");
    _asm("movl %edi,%esi");
    _asm("movl 16(%esp),%dl");       // the value in dl
    _asm("movl 20(%esp),%ecx");
    _asm("cmpl $0,%ecx");
    _asm("jle exit3");
    _asm("cld");
_asm("start3:");
    _asm("lodsb");
    _asm("addb %dl,%al");
    _asm("stosb");
    _asm("loop start3");
_asm("exit3:");
    _asm("popl %edi");
    _asm("popl %esi");
    _asm("ret");
}

void __declspec(naked) mem_setl(int * arr, int i, size_t n)
{
    _asm("pushl %edi");         // save register
    _asm("movl 8(%esp),%edi");  // get array address
    _asm("movl 12(%esp),%eax"); // the value in eax
    _asm("movl 16(%esp),%ecx"); // the number of array elements
    _asm("cmpl $0,%ecx");
    _asm("jle exit4");          // bail out if zero or less
    _asm("cld");                // EDI will be incremented
    _asm ("rep");
    _asm ("stosl");
_asm("exit4:");
    _asm("popl %edi");
    _asm("ret");
}

void __declspec(naked) mem_setw(short * arr, short i, size_t n)
{
    _asm("pushl %edi");
    _asm("movl 8(%esp),%edi");
    _asm("movw 12(%esp),%ax");   // the value in ax
    _asm("movl 16(%esp),%ecx");
    _asm("cmpl $0,%ecx");
    _asm("jle exit5");
    _asm("cld");
    _asm ("rep");
    _asm ("stosw");
_asm("exit5:");
    _asm("popl %edi");
    _asm("ret");
}

void __declspec(naked) mem_setb(char * arr, char i, size_t n)
{
    _asm("pushl %edi");
    _asm("movl 8(%esp),%edi");
    _asm("movw 12(%esp),%al");  // the value in al
    _asm("movl 16(%esp),%ecx");
    _asm("cmpl $0,%ecx");
    _asm("jle exit6");
    _asm("cld");
    _asm ("rep");
    _asm ("stosb");
_asm("exit6:");
    _asm("popl %edi");
    _asm("ret");
}

int main(void)
{
    int   arrl[2000];
    short arrw[2000];
    char  arrb[2000];
    mem_setl(arrl, 3, 2000);
    add_arrl(arrl, 7, 2000);
    for(int i=1990; i<2000; i++)
        printf("%d ", arrl[i]);

    printf("\n");

    mem_setw(arrw, 2, 2000);
    add_arrw(arrw, 9, 2000);
    for(int i=1990; i<2000; i++)
        printf("%d ", arrw[i]);

    printf("\n");

    mem_setb(arrb, 3, 2000);
    add_arrb(arrb, 10, 2000);
    for(int i=1990; i<2000; i++)
        printf("%d ", arrb[i]);

    printf("\n");

    return 0;
}

Back to main page