Thread: Help me correct this asm please

  1. #1
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,034

    Help me correct this asm please

    I rarely use assembly so I ended up getting this wrong somehow, would also like to just dump all registers into the 'dst' parameter, as for the reason I made this, had an idea to use executed instruction count for pseudo random numbers and the BIOS RTC will be my fallback option, I haven't found any instructions providing an instruction execution count as yet however so I welcome help in that regard too.
    Code:
    #include <inttypes.h>
    #include <string.h>
    typedef intmax_t asm_registers_t[0x10];
    
    inline void bios(
    	asm_registers_t *dst,
    	unsigned char interrupt, unsigned char ah, unsigned char al )
    {
    	(void)memset( dst, 0, sizeof(asm_registers_t) );
    	asm( "mov %ah,%1", ah );
    	asm( "mov %al,%1", al );
    	asm( "int %1", interrupt );
    }

  2. #2
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,034
    Been looking into the syntax of asm now that gospel is over and got as far as this:
    Code:
    #include <inttypes.h>
    #include <string.h>
    
    typedef unsigned int uint;
    typedef unsigned char uchar;
    typedef unsigned short ushort;
    typedef intmax_t asm_registers_t[0x10];
    
    volatile void bios(
    	asm_registers_t *dst,
    	uchar interrupt,
    	uchar ah,
    	uchar al
    );
    ...
    #include "bios.h"
    #include <stdio.h>
    
    int main() {
    #if 0
    	printf( "%s\n", PRIxMAX );
    #else
    	unsigned int i = 0;
    	asm_registers_t reg = {0};
    	bios(&reg,1u,0u,0u);
    	for ( i = 0; i < 0x10; ++i ) {
    		(void)printf(
    			"reg[%u] = %" PRIxMAX "\n",
    			i, reg[i]
    		);
    	}
    #endif
    }
    
    int hex2CHAR( int val ) 
    {
    	val &= 0xF;
    	if ( val < 10 )
    		return '0' + val;
    	return 'A' + val;
    }
    
    int hex2char( int val ) 
    {
    	val &= 0xF;
    	if ( val < 10 )
    		return '0' + val;
    	return 'a' + val;
    }
    
    volatile void bios(
    	asm_registers_t *dst,
    	uchar interrupt,
    	uchar ah,
    	uchar al
    )
    {
    	volatile ushort *word = (ushort*)(&word);
    	(void)memset( dst, 0, sizeof(asm_registers_t) );
    	fprintf( stderr, "word = %p, %hx", word, *word );
    	for ( ; *word != 0xCD00; ++word );
    	++word; *word = 0xCD00 | (uchar)interrupt;
    	asm( "mov ah,%0" : "=r" (ah) );
    	asm( "mov al,%0" : "=r" (al) );
    	asm( "int 0x00" );
    #if 0
    	asm( "mov %0,%r0" : "=m" ((*dst)[0]) );
    	asm( "mov %0,%r1" : "=m" ((*dst)[1]) );
    	asm( "mov %0,%r2" : "=m" ((*dst)[2]) );
    	asm( "mov %0,%r3" : "=m" ((*dst)[3]) );
    	asm( "mov %0,%r4" : "=m" ((*dst)[4]) );
    	asm( "mov %0,%r5" : "=m" ((*dst)[5]) );
    	asm( "mov %0,%r6" : "=m" ((*dst)[6]) );
    	asm( "mov %0,%r7" : "=m" ((*dst)[7]) );
    	asm( "mov %0,%r8" : "=m" ((*dst)[8]) );
    	asm( "mov %0,%r9" : "=m" ((*dst)[9]) );
    	asm( "mov %0,%r10" : "=m" ((*dst)[10]) );
    	asm( "mov %0,%r11" : "=m" ((*dst)[11]) );
    	asm( "mov %0,%r12" : "=m" ((*dst)[12]) );
    	asm( "mov %0,%r13" : "=m" ((*dst)[13]) );
    	asm( "mov %0,%r14" : "=m" ((*dst)[14]) );
    	asm( "mov %0,%r15" : "=m" ((*dst)[15]) );
    #endif
    	*word = 0xCD00;
    }
    But still no luck in getting it to compile

    Edit: Forgot to mention the compiler error message:
    Code:
    bios.c:50: Error: operand size mismatch for `int'
    Also forgot to add some details to those mov functions that copy all the registers, added but they still give me errors:
    Code:
    gcc -Wall -o bios bios.c -lpthread && ./bios
    bios.c: In function ‘bios’:
    bios.c:52:2: error: invalid 'asm': operand is not a specific integer, invalid operand code 'r'
       52 |  asm( "mov %0,%r0" : "=m" ((*dst)[0]) );
          |  ^~~
    bios.c:53:2: error: invalid 'asm': operand number out of range
       53 |  asm( "mov %0,%r1" : "=m" ((*dst)[1]) );
          |  ^~~
    bios.c:54:2: error: invalid 'asm': operand number out of range
       54 |  asm( "mov %0,%r2" : "=m" ((*dst)[2]) );
          |  ^~~
    bios.c:55:2: error: invalid 'asm': operand number out of range
       55 |  asm( "mov %0,%r3" : "=m" ((*dst)[3]) );
          |  ^~~
    bios.c:56:2: error: invalid 'asm': operand number out of range
       56 |  asm( "mov %0,%r4" : "=m" ((*dst)[4]) );
          |  ^~~
    bios.c:57:2: error: invalid 'asm': operand number out of range
       57 |  asm( "mov %0,%r5" : "=m" ((*dst)[5]) );
          |  ^~~
    bios.c:58:2: error: invalid 'asm': operand number out of range
       58 |  asm( "mov %0,%r6" : "=m" ((*dst)[6]) );
          |  ^~~
    bios.c:59:2: error: invalid 'asm': operand number out of range
       59 |  asm( "mov %0,%r7" : "=m" ((*dst)[7]) );
          |  ^~~
    bios.c:60:2: error: invalid 'asm': operand number out of range
       60 |  asm( "mov %0,%r8" : "=m" ((*dst)[8]) );
          |  ^~~
    bios.c:61:2: error: invalid 'asm': operand number out of range
       61 |  asm( "mov %0,%r9" : "=m" ((*dst)[9]) );
          |  ^~~
    bios.c:62:2: error: invalid 'asm': operand number out of range
       62 |  asm( "mov %0,%r10" : "=m" ((*dst)[10]) );
          |  ^~~
    bios.c:63:2: error: invalid 'asm': operand number out of range
       63 |  asm( "mov %0,%r11" : "=m" ((*dst)[11]) );
          |  ^~~
    bios.c:64:2: error: invalid 'asm': operand number out of range
       64 |  asm( "mov %0,%r12" : "=m" ((*dst)[12]) );
          |  ^~~
    bios.c:65:2: error: invalid 'asm': operand number out of range
       65 |  asm( "mov %0,%r13" : "=m" ((*dst)[13]) );
          |  ^~~
    bios.c:66:2: error: invalid 'asm': operand number out of range
       66 |  asm( "mov %0,%r14" : "=m" ((*dst)[14]) );
          |  ^~~
    bios.c:67:2: error: invalid 'asm': operand number out of range
       67 |  asm( "mov %0,%r15" : "=m" ((*dst)[15]) );
          |  ^~~
    Compilation failed.
    Last edited by awsdert; 05-10-2020 at 02:22 PM.

  3. #3
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,034
    Well I managed to fix most of the errors, the one that remains is that size mismatch which I have no idea how to fix since I don't even know what the problem is
    Code:
    int set_page_perm( void * addr, int perm )
    {
    	size_t size = sysconf( _SC_PAGE_SIZE );
    	addr -= ((uintptr_t)addr % size);
    	return mprotect( addr, size, perm );
    }
    
    volatile int bios(
    	asm_registers_t *dst,
    	uchar interrupt,
    	uchar ah,
    	uchar al
    )
    {
    	int perm = PROT_READ | PROT_EXEC;
    	if ( set_page_perm( bios, perm | PROT_WRITE ) == -1 )
    		return -1;
    	volatile ushort *word = (ushort*)(&word);
    	(void)memset( dst, 0, sizeof(asm_registers_t) );
    	fprintf( stderr, "word = %p, %hx", word, *word );
    	for ( ; *word != 0xCD00; ++word );
    	++word; *word = 0xCD00 | (uchar)interrupt;
    	asm( "mov %%ah,%0" : : "r" (ah) : "ah" );
    	asm( "mov %%al,%0" : : "r" (al) : "al" );
    	asm( "int 0x00" );
    	asm( "mov %0,%%rax" : "=m" ((*dst)[0]) );
    	asm( "mov %0,%%rcx" : "=m" ((*dst)[1]) );
    	asm( "mov %0,%%rdx" : "=m" ((*dst)[2]) );
    	asm( "mov %0,%%rbx" : "=m" ((*dst)[3]) );
    	asm( "mov %0,%%rsp" : "=m" ((*dst)[4]) );
    	asm( "mov %0,%%rbp" : "=m" ((*dst)[5]) );
    	asm( "mov %0,%%rsi" : "=m" ((*dst)[6]) );
    	asm( "mov %0,%%rdi" : "=m" ((*dst)[7]) );
    	asm( "mov %0,%%r8" : "=m" ((*dst)[8]) );
    	asm( "mov %0,%%r9" : "=m" ((*dst)[9]) );
    	asm( "mov %0,%%r10" : "=m" ((*dst)[10]) );
    	asm( "mov %0,%%r11" : "=m" ((*dst)[11]) );
    	asm( "mov %0,%%r12" : "=m" ((*dst)[12]) );
    	asm( "mov %0,%%r13" : "=m" ((*dst)[13]) );
    	asm( "mov %0,%%r14" : "=m" ((*dst)[14]) );
    	asm( "mov %0,%%r15" : "=m" ((*dst)[15]) );
    	*word = 0xCD00;
    	return set_page_perm( bios, perm );
    }

  4. #4
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,034
    I think I fixed the error, either way I haven't been able to change the interrupt yet, on another note I tried adding in another register I learned off only for the compiler to say MOV doesn't support that so I tried a work around of XOR, OR then MOV but the compiler is also complaining there, any help would be appreciated.
    Code:
    int bios( asm_registers_t *dst, uchar interrupt, uchar ah, uchar al )
    {
    	int ret = -1;
    	int perm = PROT_READ | PROT_EXEC;
    	ushort *word = (ushort*)bios;
    	
    	if ( set_page_perm( bios, perm | PROT_WRITE ) == -1 )
    		goto fail;
    	
    	(void)memset( dst, 0, sizeof(asm_registers_t) );
    	(void)fprintf( stderr, "ptr   = %p\n", dst );
    	
    #if 0
    	print_word( word );
    	asm( "mov %0,%%rbp" : "=m" (*word) );
    #endif
    
    	for ( ; *word != 0xCD09; ++word )
    	{
    		print_word( word );
    	}
    	
    	++word;
    	if ( *((uchar*)word) != 0xCD )
    	{
    		fprintf( stderr, "Failed to find 0xCD # (aka int #)\n" );
    		return -1;
    	}
    	
    	*((ushort*)word) = 0xCD | ((ushort)interrupt << CHAR_BIT);
    	
    	asm( "mov %%ah,%0" : : "r" (ah) : "ah" );
    	asm( "mov %%al,%0" : : "r" (al) : "al" );
    	asm( "nop" );
    	asm( "nop" );
    	asm( "nop" );
    	asm( "nop" );
    	asm( "nop" );
    	asm( "nop" );
    	asm( "nop" );
    	asm( "nop" );
    	asm( "int $0x00" : : : "cc", "memory" );
    	ret = 0;
    	fail:
    	asm( "mov %0,%%rax" : "=m" ((*dst)[REG_RAX]) );
    	asm( "mov %0,%%rcx" : "=m" ((*dst)[REG_RCX]) );
    	asm( "mov %0,%%rdx" : "=m" ((*dst)[REG_RDX]) );
    	asm( "mov %0,%%rbx" : "=m" ((*dst)[REG_RBX]) );
    	asm( "mov %0,%%rsp" : "=m" ((*dst)[REG_RSP]) );
    	asm( "mov %0,%%rbp" : "=m" ((*dst)[REG_RBP]) );
    	asm( "mov %0,%%rsi" : "=m" ((*dst)[REG_RSI]) );
    	asm( "mov %0,%%rdi" : "=m" ((*dst)[REG_RDI]) );
    	asm( "mov %0,%%r8" : "=m" ((*dst)[REG_R08]) );
    	asm( "mov %0,%%r9" : "=m" ((*dst)[REG_R09]) );
    	asm( "mov %0,%%r10" : "=m" ((*dst)[REG_R10]) );
    	asm( "mov %0,%%r11" : "=m" ((*dst)[REG_R11]) );
    	asm( "mov %0,%%r12" : "=m" ((*dst)[REG_R12]) );
    	asm( "mov %0,%%r13" : "=m" ((*dst)[REG_R13]) );
    	asm( "mov %0,%%r14" : "=m" ((*dst)[REG_R14]) );
    	asm( "mov %0,%%r15" : "=m" ((*dst)[REG_R15]) );
    	asm( "xor %%rax,%%rax" : : : "rax" );
    	asm( "or %%rax,%%rip" : : : "rax" );
    	asm( "mov %0,%%rax"	: "=m" ((*dst)[REG_RIP]) );
    	
    	return (ret == 0) ? set_page_perm( bios, perm ) : ret;
    }
    Edit: Oops, forgot to add the error message:
    Code:
    bios.c:114: Error: operand type mismatch for `or'

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Which is correct?
    By mramazing in forum C++ Programming
    Replies: 7
    Last Post: 12-29-2010, 02:11 PM
  2. Am I correct on this?
    By caduardo21 in forum C Programming
    Replies: 5
    Last Post: 07-11-2005, 11:41 PM
  3. correct me please
    By ssharish in forum C++ Programming
    Replies: 3
    Last Post: 05-28-2005, 09:10 AM
  4. correct me please
    By ssharish in forum C Programming
    Replies: 3
    Last Post: 03-20-2005, 05:40 AM

Tags for this Thread