首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >编译器标志更改代码行为(O2,Ox)

编译器标志更改代码行为(O2,Ox)
EN

Stack Overflow用户
提问于 2011-11-11 19:53:49
回答 2查看 318关注 0票数 2

下面的代码使用标志Od,O1可以正常工作,但是使用O2,Ox会失败。你知道为什么吗?

编辑:所谓“失败”,我的意思是这个函数什么也不做,似乎只是返回。

代码语言:javascript
复制
void thread_sleep()
{
    listIterator nextThread = getNextThread();
    void * pStack = 0;
    struct ProcessControlBlock * currPcb = pPCBs->getData(currentThread);
    struct ProcessControlBlock * nextPcb = pPCBs->getData(nextThread);

    if(currentThread == nextThread)
    {
        return;
    }
    else
    {
        currentThread = nextThread;
        __asm pushad            // push general purpose registers
        __asm pushfd            // push control registers
        __asm mov pStack, esp   // store stack pointer in temporary

        currPcb->pStack = pStack;   // store current stack pointer in pcb
        pStack = nextPcb->pStack;   // grab new stack pointer from pcb

        if(nextPcb->state == RUNNING_STATE)// only pop if function was running before
        {
            __asm mov esp, pStack       // restore new stack pointer
            __asm popfd
            __asm popad;
        }
        else
        {
            __asm mov esp, pStack       // restore new stack pointer
            startThread(currentThread);
        }
    }
}

//实现建议后:(仍然不起作用)

代码语言:javascript
复制
listIterator nextThread = getNextThread();
struct ProcessControlBlock * currPcb = pPCBs->getData(currentThread);
struct ProcessControlBlock * nextPcb = pPCBs->getData(nextThread);
void * pStack = 0;
void * pNewStack = nextPcb->pStack; // grab new stack pointer from pcb
pgVoid2 = nextPcb->pStack;

if(currentThread == nextThread)
{
    return;
}
else
{
    lastThread = currentThread; // global var
    currentThread = nextThread;


    if(nextPcb->state == RUNNING_STATE)// only pop if function was running before
    {
        __asm pushad                // push general purpose registers
        __asm pushfd                // push control registers
        __asm mov pgVoid1, esp      // store stack pointer in temporary
        __asm mov esp, pgVoid2      // restore new stack pointer
        __asm popfd
        __asm popad;

        {
            struct ProcessControlBlock * pcb = pPCBs->getData(lastThread);
            pcb->pStack = pgVoid1; // store old stack pointer in pcb
        }
    }
    else
    {
        __asm pushad                // push general purpose registers
        __asm pushfd                // push control registers
        __asm mov pgVoid1, esp  // store stack pointer in temporary
        __asm mov esp, pgVoid2      // restore new stack pointer

        {
            struct ProcessControlBlock * pcb = pPCBs->getData(lastThread);
            pcb->pStack = pgVoid1; // store old stack pointer in pcb
        }
        startThread(currentThread);
    }
}
EN

回答 2

Stack Overflow用户

发布于 2011-11-11 20:12:12

这很可能是因为您的编译器没有在更高的优化级别上使用特定的帧指针寄存器,从而释放了一个额外的通用寄存器。

这意味着编译器使用堆栈指针的偏移量来访问局部变量pStack。在堆栈指针被pushadpushfd调整后,它无法正确执行此操作-它不希望堆栈指针发生变化。

要解决这个问题,在正确恢复堆栈指针之前,不应该将任何C代码放在这些asm语句后面:从第一个pushadpopadstartThread()的所有内容都应该在汇编程序中。这样,您就可以加载本地变量的地址,并确保正确完成访问。

票数 3
EN

Stack Overflow用户

发布于 2011-11-13 06:26:11

在使用内联汇编程序时,您可能希望了解在使用各种-Ox选项编译代码时,代码实际上是如何修改的(或者是否被修改)。在你的二进制文件上试试这个:

代码语言:javascript
复制
objdump -s your_program

它给出了一堆代码,但是找到相应的代码段应该不是很难(搜索您的程序集或函数名)。

顺便说一句,我被教导说大量的优化在内联汇编中做得不是很好,因此我倾向于将汇编例程分离到.S文件中。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8093614

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档