Thursday, September 25, 2014

Parameter passing inline gcc assembly error

This does not work: 

static void beep(unsigned short divisor)
{
    __asm__ volatile(
// set 8254 timer contol register to accept divisor
// IO port: 0x43
// 0xb6: 1011 0110
// channel2, access mode lo and hi, square wave
                "movb $0xb6, %%al\n"
                "out %%al, $0x43\n"

// load the divisor into ax
"mov %0, %%ax\n"

// set the low 8 bits of time2 counter
// IO port: 0x42
                "out %al, $0x42\n"

// set the high 8 bits of timer2 counter
// IO port: 0x42
                "movb %ah, %al\n"
                "out %al, $0x42\n"

// configure Speaker IO controller Port 0x61
// save the contents of 0x61
    "in $0x61, %al\n"
"movb %al, %ah\n"
// set bit 0, 1 to 1; enables the timer and NAND gate
                "or $0x3, %al\n"
                "out %al, $0x61\n"

// Run spin loop to delay
"mov $0x50E0, %cx\n"
"BEEP_DELAY: nop\n"
"nop\n"
"loop BEEP_DELAY\n"

// Trun off the speaker
"mov %ah, %al\n"
"out %al, $0x61"
:
:"r" (divisor)
   );
}

This works: 

static void beep(unsigned short divisor)
{
    __asm__ volatile(
// set 8254 timer contol register to accept divisor
// IO port: 0x43
// 0xb6: 1011 0110
// channel2, access mode lo and hi, square wave
                "movb $0xb6, %%al\n"
                "out %%al, $0x43\n"

// load the divisor into ax
"mov %0, %%ax"
:
:"r" (divisor)
   );

    __asm__ volatile(

// set the low 8 bits of time2 counter
// IO port: 0x42
                "out %al, $0x42\n"

// set the high 8 bits of timer2 counter
// IO port: 0x42
                "movb %ah, %al\n"
                "out %al, $0x42\n"

// configure Speaker IO controller Port 0x61
// save the contents of 0x61
    "in $0x61, %al\n"
"movb %al, %ah\n"
// set bit 0, 1 to 1; enables the timer and NAND gate
                "or $0x3, %al\n"
                "out %al, $0x61\n"

// Run spin loop to delay
"mov $0x50E0, %cx\n"
"BEEP_DELAY: nop\n"
"nop\n"
"loop BEEP_DELAY\n"

// Trun off the speaker
"mov %ah, %al\n"
"out %al, $0x61\n"
   );
}

No comments: