标题总结了这一点。
如果在rcl指令为envoke且a1为零时预先设置进位标志,则顶位(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).
在我看来,如果源值为零,则根本不会执行任何操作,这是不正确的!
发布于 2019-10-03 11:30:13
我的问题(有三个)的明显原因是C优化器删除了代码,因为它不知道汇编代码对某些变量有任何影响。
(我的代码示例与6809/6309 CPU仿真器有关)
我将总结这三个问题。
(在这篇文章中记录)
(示例不可能)
以下代码:
static void(*JmpVec1[256])(void) = { ... };
...
unsigned char memByte = MemRead8(PC_REG++);
JmpVec1[memByte](); // Execute instruction pointed to by byte @ PC_REG
CycleCounter += instcycl1[memByte]; // Add instruction cycles
只有在使用以下代码时才能正常工作:
static void(*JmpVec1[256])(void) = { ... };
...
unsigned char memByte = MemRead8(PC_REG++);
if (memByte == 0x34) // Just doesn't like instruction 0x34 Pushs register_list
{
JmpVec1[memByte](); // Execute instruction pointed to by PC_REG
}
else
{
JmpVec1[memByte](); // Execute instruction pointed to by PC_REG
}
CycleCounter += instcycl1[memByte]; // Add instruction cycles
由于C代码不知道这437条仿真指令中的任何一条都在做什么,或者这些指令有什么作用,所以它为什么选择指令0x34来停止工作是一个谜。
修复了这个问题并允许我删除混淆的代码并允许我重新启用C优化的是使CycleCounter (int)变量易失。
修复了我所有的问题!
这个问题变得更加复杂,因为vscode中没有反汇编支持,这使得汇编例程的调试变得极其困难。
如果有人在Linux上使用好的C/汇编IDE,请发表评论。
https://stackoverflow.com/questions/58184817
复制相似问题