Thread: asmtest.c:16: Error: operand type mismatch for `jmp'

  1. #1
    Registered User
    Join Date
    Apr 2011
    Posts
    15

    asmtest.c:16: Error: operand type mismatch for `jmp'

    I am trying to jmp to the offset address of a program that I wrote using nasm.

    C source code:

    Code:
    char code[] = {0x66, 0xB8, 0x04, 0x00, 0x00, 0x00, 0x66, 0xBB, 0x01, 0x00, 0x00, 0x00,  
                   0x66, 0xB9, 0x28, 0x00, 0x00, 0x00, 0x66, 0xBA, 0x0C, 0x00, 0x00, 0x00,
                   0xCD, 0x80, 0x66, 0xB8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
                   0x00, 0x20, 0x66, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26,
                   0xCD, 0x80, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72,
                   0x6C, 0x64, 0x0A};             
    
    int accumulator;
    
    int main(void) {
    jump (code);
    return 0;
    }
    
    int jump (char *addr) {
     asm("jmp %1"
         : "=r" (accumulator)
         : "0" (accumulator), "g" (addr)
         : "0"); 
     return 0;
    }
    assembly:
    Code:
        1                                  _start:
         2 00000000 66B804000000                   mov eax, 4
         3 00000006 66BB01000000                   mov ebx, 1
         4 0000000C 66B9[28000000]                 mov ecx, msg
         5 00000012 66BA0C000000                   mov edx, msg_l
         6 00000018 CD80                           int 80h
         7                                  
         8 0000001A 66B801000000                   mov eax, 1
         9 00000020 66BB00000000                   mov ebx, 0
        10 00000026 CD80                           int 80h 
        11                                  
        12 00000028 48656C6C6F20576F72-            msg:     db "Hello World", 10
        13 00000031 6C640A             
        14                                         msg_l:   equ $-msg
        15

  2. #2
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    This may not be possible if the processor and the operating system support data execution protection. Wiki article:

    Data Execution Prevention - Wikipedia, the free encyclopedia

  3. #3
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Try changing this
    Code:
      asm("jmp %1"
    to this
    Code:
      asm("jmp *%1"
    (Note the added asterisk.)
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  4. #4
    Registered User
    Join Date
    Apr 2011
    Posts
    15
    @oogabooga
    The compiler tells me that "*" when used within inline assembly is an unrecognized character.

  5. #5
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    What compiler???
    I'm assuming you're on *nix and using gcc, but....

    Your assembly code looks a little wacky, so I fixed it up a bit.
    Does this work for you:
    Code:
    char code[] = {0xB8, 0x04, 0x00, 0x00, 0x00,        // movl eax, 4
                   0xBB, 0x01, 0x00, 0x00, 0x00,        // movl ebx, 1
                   0xB9, 0x00, 0x00, 0x00, 0x00,        // movl ecx, msg
                   0xBA, 0x0C, 0x00, 0x00, 0x00,        // movl edx, msg_l
                   0xCD, 0x80,                          // int 80h
                   0xC3,                                // ret
                   0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20,  // Hello world\n
                   0x57, 0x6F, 0x72, 0x6C, 0x64, 0x0A};             
    
    int jump (char *addr) {
        asm("call *%0"
           :
           : "r" (addr)
           : "%eax", "%ebx", "%ecx", "%edx");
        return 0;
    }
    
    int main(void) {
        *(int*)&code[11] = (unsigned)code + 23U;   // set address of string
        jump(code);
        return 0;
    }
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  6. #6
    Registered User
    Join Date
    Apr 2011
    Posts
    15
    What compiler???

    I am using gcc on 64-bit Linux. The code that you provided compiles, however it generates the following warning:

    warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
    *(int*)&code[11] = (unsigned)code + 23U; // set address of string
    Upon execution the executable generates segmentation fault (core dumped) error.
    Last edited by Jacob Dahlen; 08-30-2013 at 06:03 AM.

  7. #7
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Sadly, I have not yet upgraded (mostly from pure laziness...).
    But it's fairly obvious what you need to do:
    - Change the movl's to movq's.
    - Change the values to 64-bit values.
    - Change the "set address of string" operation to this:

    *(char**)(code+OFFSET1) = code + OFFSET2U; // set address of string

    - Change the offsets (OFFSET1, OFFSET2) in the "set address of string" operation to the new offsets.
    OFFSET1 is the offset of the operand for the movq that puts msg into the c register.
    OFFSET2 is the offset of your string.
    These offsets are zero-based from the beginning of your code array.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  8. #8
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    Quote Originally Posted by oogabooga View Post
    But it's fairly obvious what you need to do:
    - Change the movl's to movq's.
    Is the code supposed to be movl eax,... or movq rax,... ?

  9. #9
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Quote Originally Posted by rcgldr View Post
    Is the code supposed to be movl eax,... or movq rax,... ?
    I believe it should be movq and if "rax" means 64-bit register, then that's what I meant.
    However, I know nothing of 64-bit instructions, so I'm unsure.
    If you could show me the instruction encoding by disassembling instructions that move an immediate 64-bit data operand into each of the a, b, c, d registers then I could hand-assemble the above code into a working program.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  10. #10
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    Quote Originally Posted by oogabooga View Post
    I believe it should be movq and if "rax" means 64-bit register, then that's what I meant.
    Yes, al, ah, mean 8 bit registers, ax means 16 bit register, eax means 32 bit register, rax means 64 bit register. My guess is that the op is using an assembler to generate the array of bytes in code[].

  11. #11
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Quote Originally Posted by rcgldr View Post
    Yes, al, ah, mean 8 bit registers, ax means 16 bit register, eax means 32 bit register, rax means 64 bit register. My guess is that the op is using an assembler to generate the array of bytes in code[].
    The OP said he used nasm, so you're right. However, he assembled it as 16-bit instructions which I updated to 32-bit instructions by hand (simply removing a single byte from the front of each instruction). But he actually needs 64-bit instructions, at least to load rcx with a 64-bit address.

    He also didn't update the string address based on the location of the code array, which is necessary since the original machine code is based at address 0. Of course, it would be easier to simply use a separate string and pass in its address.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Confusing array of char pointer type mismatch
    By tkks in forum C Programming
    Replies: 4
    Last Post: 04-21-2013, 11:24 AM
  2. Type Mismatch Error
    By sanks85 in forum C Programming
    Replies: 1
    Last Post: 04-01-2013, 01:58 AM
  3. Replies: 16
    Last Post: 08-02-2011, 12:30 PM
  4. Data type mismatch in criteria expression ERROR
    By Aga^^ in forum C# Programming
    Replies: 2
    Last Post: 02-11-2009, 01:21 AM
  5. Type mismatch warning
    By Opel_Corsa in forum C Programming
    Replies: 5
    Last Post: 10-11-2006, 10:34 AM