Showing posts with label computer science. Show all posts
Showing posts with label computer science. Show all posts

Saturday, 23 February 2019

Assembly: Sub-routine to display a range of characters

This program repeatedly calls a sub-routine to display a range of characters.

The first and last character to be displayed in each range can be set using the al and cl 8-bit registers before calling the sub-routine.



Code:

program display_chars;

#include( "stdlib.hhf" )


// Phil Gardner

procedure displayCharRange; @noframe; @nodisplay;
begin displayCharRange;

    keepDisplaying:

        stdout.put( ( type char al ), " " );
        inc( al );
        cmp( al, cl );
    jle keepDisplaying;

    ret();

end displayCharRange;


// - - - - -

begin display_chars;


    // Display all upper-case letters

    mov( $41, al );
    mov( $5A, cl );
    call displayCharRange;

    stdout.put( nl );

    // Display all lower-case letters

    mov( $61, al );
    mov( $7A, cl );
    call displayCharRange;

    stdout.put( nl );

    // Display all numeric digits

    mov( $30, al );
    mov( $39, cl );
    call displayCharRange;

    stdout.put( nl );

    // Display punctuation symbols

    mov( $21, al );
    mov( $2F, cl );
    call displayCharRange;

    
    mov( $3A, al );
    mov( $40, cl );
    call displayCharRange;

    mov( $5B, al );
    mov( $60, cl );
    call displayCharRange;

    mov( $7B, al );
    mov( $7E, cl );
    call displayCharRange;

    stdout.put( nl );

end display_chars;

Friday, 22 February 2019

Assembly: Push the stack over

How much data can you push on to the stack before your program falls over?



Let's have a look then...

program stack_zapper;

#include( "stdlib.hhf" )


// Phil Gardner


begin stack_zapper;


    stdout.put( nl );
    stdout.put( "Repeatedly push 4 byte value on to the stack." );
    stdout.put( nl );


    mov( $0000029A, eax );


    stdout.put( "eax = " );
    stdout.put( eax );

    stdout.put( nl, nl );

    mov( $00000000, ebx );


infiniteLoop:


    stdout.put( "Stack pointer = " );
    stdout.put( esp );

    stdout.put( nl );

    mov( $00004000, ecx );


pushBigChunk:


    push( eax );


    dec( ecx );


    jge pushBigChunk;


    stdout.put( "Pushed another 16 KB on to stack" );
    stdout.put( stdio.tab );


    inc( ebx );


    stdout.put( ebx );
    stdout.put( " x 16 KB" );
    stdout.put( stdio.tab );


    jmp infiniteLoop;


end stack_zapper;

Assembly: Commencing countdown, engines on

How long does it take a program written in assembly language to countdown from 1 billion to zero?


Find out for yourself, lazybones:

program countdown;
#include( "stdlib.hhf" )
static
    // Will countdown from 1 billion
    num: dword := $3B9ACA00;

begin countdown;
    mov( num, eax );
    stdout.put( "Starting from " );
    stdout.put( eax );
    stdout.put( " (1 billion)" );
    stdout.put( nl );

    countDownLoop:
        dec( eax );
        jg countDownLoop;
    stdout.put( "Reached zero. Splat." );
    stdout.put( nl );

end countdown;
(Post-script: It was approx. 300 times faster than Python.)

Assembly: Determine length of a string

Ssshh! It's a DELIBERATELY ANNOYING LOW-LEVEL PROGRAM
This is not the sort of thing that people should EVER mess about with.

EVER.

Apparently.

Because it's written in HLA assembly language for an Intel processor.

Schools and colleges in the UK don't like assembly language. It's official.


So here's the code:
program determine_string_length;

#include( "stdlib.hhf" )

static
    zeroTerminatedString:   char;    @nostorage;
    byte    "Hello from RAM", 0;

begin determine_string_length;
        mov( &zeroTerminatedString, ebx );
        stdout.put( nl );
        stdout.put( "Base address where string begins is held in register ebx = " );
        stdout.put( ebx );
        stdout.put( nl, nl );

        mov( 0, eax );
    visitCharacter:
        mov( ebx, ecx );
        add( eax, ecx );

        cmp( (type byte [ecx]), 0 );
        jz outputLength;

        stdout.put( "Index address eax = " );
        stdout.put( eax );
        stdout.put( stdio.tab );

        stdout.put( "Mem address ebx+eax = " );
        stdout.put( ecx );
        stdout.put( stdio.tab );

        stdout.put( "Contents = " );
        stdout.put( ( type byte [ecx] ) );
        stdout.put( stdio.tab );

        stdout.put( "ASCII char = " );
        stdout.put( ( type char [ecx] ) );
        stdout.put( nl );

        inc( eax );
        jmp visitCharacter;

    outputLength:

        stdout.put( nl );
        stdout.put( "Length held in register eax = " );

        stdout.put( ( type uns32 eax ) );
        stdout.put( nl );

end determine_string_length;