Assembly x86程序集rcl al,1在al等于零时未清除进位标志

Assembly x86程序集rcl al,1在al等于零时未清除进位标志,assembly,x86,Assembly,X86,标题概括了这一点 如果之前在rcl指令为envoke且al为零时设置了进位标志,则顶部位(0)不会移到进位 以下代码说明: mov al,0 stc setc byte ptr [before] rcl al,1 ; rotate left one bit through carry flag (multiply by 2 once) setc byte ptr [after] 因此,输出: before = 01 after = 01 进位标志未按预期清除。阅读英特尔手册: The shi

标题概括了这一点

如果之前在rcl指令为envoke且al为零时设置了进位标志,则顶部位(0)不会移到进位

以下代码说明:

mov al,0
stc
setc byte ptr [before]
rcl al,1 ; rotate left one bit through carry flag (multiply by 2 once)
setc byte ptr [after]
因此,输出:

before = 01
after = 01
进位标志未按预期清除。阅读英特尔手册:

The shift arithmetic left (SAL) and shift logical left (SHL) instructions perform the same operation; they shift the
bits in the destination operand to the left (toward more significant bit locations). For each shift count, the most
significant bit of the destination operand is shifted into the CF flag, and the least significant bit is cleared (see
Figure 7-7 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1).

在我看来,如果源值为零,那么什么都不做,这是不正确的

我的问题(有三个)的明显原因是C Optimizer删除了代码,因为它不知道汇编代码对某些变量有任何影响

(我的代码示例与6809/6309 CPU仿真器有关)

我将总结这三个问题

  • rcl组装说明似乎没有设置进位标志

    (记录在本帖中)

  • 当对C代码进行优化编译时,汇编代码的运行速度将慢100-1000倍

    (示例不可能)

  • 某些代码需要模糊处理才能使代码正常工作

  • 以下代码:

    staticvoid(*JmpVec1[256])(void)={…};
    ...
    无符号字符memByte=MemRead8(PC_REG++);
    JmpVec1[memByte]();//执行字节@PC_REG指向的指令
    CycleCounter+=instcycl1[memByte];//添加指令周期
    
    仅在使用以下代码时才起作用:

    staticvoid(*JmpVec1[256])(void)={…};
    ...
    无符号字符memByte=MemRead8(PC_REG++);
    if(memByte==0x34)//只是不喜欢指令0x34推送寄存器\u列表
    {
    JmpVec1[memByte]();//执行PC_REG指向的指令
    }
    其他的
    {
    JmpVec1[memByte]();//执行PC_REG指向的指令
    }
    CycleCounter+=instcycl1[memByte];//添加指令周期
    
    由于C代码不知道437条模拟指令中的任何一条在做什么,也不知道这些指令有什么影响,所以它选择指令0x34停止工作是一个谜

    修复了这个问题并允许我删除模糊代码并允许我重新启用C优化的是使CycleCounter(int)变量不稳定

    修正了我所有的问题

    由于vscode中没有反汇编支持,使得汇编例程的调试变得极其困难,因此这个问题进一步复杂化


    如果有人在Linux上使用好的C/assembly IDE,请发表评论。

    我的问题(有三个)的明显原因是C Optimizer删除了代码,因为它不知道汇编代码对某些变量有任何影响

    (我的代码示例与6809/6309 CPU仿真器有关)

    我将总结这三个问题

  • rcl组装说明似乎没有设置进位标志

    (记录在本帖中)

  • 当对C代码进行优化编译时,汇编代码的运行速度将慢100-1000倍

    (示例不可能)

  • 某些代码需要模糊处理才能使代码正常工作

  • 以下代码:

    staticvoid(*JmpVec1[256])(void)={…};
    ...
    无符号字符memByte=MemRead8(PC_REG++);
    JmpVec1[memByte]();//执行字节@PC_REG指向的指令
    CycleCounter+=instcycl1[memByte];//添加指令周期
    
    仅在使用以下代码时才起作用:

    staticvoid(*JmpVec1[256])(void)={…};
    ...
    无符号字符memByte=MemRead8(PC_REG++);
    if(memByte==0x34)//只是不喜欢指令0x34推送寄存器\u列表
    {
    JmpVec1[memByte]();//执行PC_REG指向的指令
    }
    其他的
    {
    JmpVec1[memByte]();//执行PC_REG指向的指令
    }
    CycleCounter+=instcycl1[memByte];//添加指令周期
    
    由于C代码不知道437条模拟指令中的任何一条在做什么,也不知道这些指令有什么影响,所以它选择指令0x34停止工作是一个谜

    修复了这个问题并允许我删除模糊代码并允许我重新启用C优化的是使CycleCounter(int)变量不稳定

    修正了我所有的问题

    由于vscode中没有反汇编支持,使得汇编例程的调试变得极其困难,因此这个问题进一步复杂化


    如果有人在Linux上使用一个好的C/assembly IDE,请发表评论。

    这在a中正常工作,给我
    before=1,after=0,al=1
    。确保调试器在检查变量内容的最后一行停止。您也可以使用
    adc al,al
    作为
    rcl al,1
    的更有效替代方法。它写入所有标志,而不必合并以保留一些未修改的标志。不管怎样,这看起来不像是一个问题,因为问题在于你是如何检查结果的。否则(不合理)您的CPU损坏或(更合理)您的汇编器损坏。也许你在MacOS上有一个错误的NASM生成错误的寻址模式?最后,我在VS2015上实现了这一点,但在使用jwasm移植到VScode时无法实现。原来我有一个错误(在调用C代码中),VS2015正在避免。是的,所以更正了C代码,一切都很好,rcl正在按文档记录的方式工作。@WallyZ酷!如果可能的话,请将您的解决方案作为答案发布。这在a中是正确的,给我
    before=1,after=0,al=1
    。确保调试器在检查变量内容的最后一行停止。您也可以使用
    adc al,al
    作为
    rcl al,1
    的更有效替代方法。它写入所有标志,而不必合并以保留一些未修改的标志。不管怎样,这看起来不像是一个问题,因为问题在于你是如何检查结果的。否则(不合理)您的CPU损坏或(更合理)您的汇编器损坏。佩哈