Creating a C function without compiler generated by prolog / epilog and RET?

Consider this function:

void foo(){
    //do something
}

In the assembly, it will look something like this (not exact):

push something

;do stuff

pop something
ret

But I do not need this generated code (RET, PUSH, POP ...). I just want the label to be a block of code, so I have to go back myself:

void bar(){
    //do something
    asm("iret") //i want to use this function as a ISR
}

and in the assembly it will look something like this:

; do something
iret

without PUSH, POP or RET. Are there any preprocessor directives or keywords that would allow me to accomplish this?

I use GCC and NASM under Windows, and I am trying to create my own interrupt service routines (ISRs).

+4
source share
3 answers

, . , , iret .


GCC ( NASM) :

/* Make C extern declarations of the ISR entry points */    
extern void isr_test1(void);
extern void isr_test2(void);

/* Define a do nothing ISR stub */
__asm__(".global isr_test1\n"
        "isr_test1:\n\t"
        /* Other stuff here */
        "iret");    

/* Define an ISR stub that makes a call to a C function */
__asm__(".global isr_test2\n"
        "isr_test2:\n\t"
        "cld\n\t"                    /* Set direction flag forward for C functions */
        "pusha\n\t"                  /* Save all the registers */
        /* Other stuff here */
        "call isr_test2_handler\n\t"
        "popa\n\t"                   /* Restore all the registers */
        "iret");

void isr_test2_handler(void)
{
    return;
}

__asm__ GCC . (ISR) .globl ( , ).

. , , iret , C. . C , , C CLD. 32- . 64- , PUSHA POPA.

. GCC Windows , , , _ ( ). :

/* Make C extern declarations of the ISR entry points */    
extern void isr_test1(void);
extern void isr_test2(void);

/* Define a do nothing ISR stub */
__asm__(".global _isr_test1\n"
        "_isr_test1:\n\t"
        /* Other stuff here */
        "iret");    

/* Define an ISR stub that makes a call to a C function */
__asm__(".global _isr_test2\n"
        "_isr_test2:\n\t"
        "cld\n\t"                    /* Set direction flag forward for C functions */
        "pusha\n\t"                  /* Save all the registers */
        /* Other stuff here */
        "call _isr_test2_handler\n\t"
        "popa\n\t"                   /* Restore all the registers */
        "iret");

void isr_test2_handler(void)
{
    return;
}

MSVC/MSV++

Microsoft C/++ . :

- Microsoft C. , naked storage-class, . , /, . .

:

__declspec(naked) int isr_test(void)
{
    /* Function body */
    __asm { iret };
}

, GCC.


GCC 7.x + x86/x86-64

GCC 7.0+ __attribute__((interrupt)) . x86 x86-64:

, , ( , , ). , , . IRET RET . , EFLAGS, IRET, . GCC MPX, SSE, MMX x87, GCC -mgeneral-regs-only.

. - , C- , , . , , , ( : int 0x80 Linux). .

+4

:

, extern c:

bits 32

global _bar
extern _foo

section .data

section .text

_bar:
    call _foo
    iret

C:

void foo(){
    //do your stuff here
}

extern void bar();

//bar is now your "naked" function

nasm gcc

+2

I assume that you need the syntax of the function without having the C compiler. You can do this by contacting your build function (and then you will need to copy the correct things onto the stack, of course).

Your build procedures only require an entry point for the C compiler, for example:

Part of the assembly will contain the following header:

global my_function 
my_function:
push r1
push r2
; Code 
ret

corresponds to:

void  my_function ( int arg1, char arg2 ); 
0
source

Source: https://habr.com/ru/post/1674431/


All Articles