我现在正在参加集会的本科课程。我对TA如何评分我的任务有一些不符之处。我只是测试进位,零,符号和溢出标志的状态。
这是我出错的状态标志问题之一:
mov ah, 255
mov al, -1
cmp ah, al
我的解决方案:CF=0, ZF=1, SF=0, OF=0
他的解决方案:CF=0, ZF=0, SF=1, OF=1
有人可以帮我验证哪个是正确的?我不认为我的错了,但如果可以,你能解释一下答案是否正确?
答案 0 :(得分:2)
你的答案确实是正确的。
Intel Software Developer’s Manual的第1卷描述了每个标志:
CF(位0)进位标志 - 设置算术运算是否从结果的最高有效位产生进位或借位;否则清除。该标志表示无符号整数运算的溢出条件。
ZF(第6位)零标志 - 如果结果为零则设置;否则就清楚了。
SF(第7位)符号标志 - 设置等于结果的最高有效位,即有符号整数的符号位。 (0表示正值,1表示负值。)
OF(第11位)溢出标志 - 设置整数结果是否过大,正数或过小的负数(不包括符号位)以适合目标操作数;否则清除。该标志表示有符号整数(二进制补码)算术的溢出条件。
代码中的标志由cmp
指令设置,指令集参考卷2表示:
比较第一个源操作数和第二个源操作数并设置 根据结果,EFLAGS寄存器中的状态标志。比较是 通过从第一个操作数中减去第二个操作数然后设置来执行 状态标志的方式与SUB指令相同。
SUB指令执行整数减法。它评估两者的结果 有符号和无符号整数操作数,并设置OF和CF标志以指示 分别在有符号或无符号结果中溢出。 SF标志表示符号 已签名的结果。
首先,我们发现al
和ah
都具有相同的值:所有八位都是1
。
由于CMP
设置了SUB
之类的标记,我们只评估0xFF - 0xFF
,这当然是零。
OF,CF - 没有溢出,因此OF=0
和CF=0
。
ZF - 答案是零,所以ZF=1
。
SF - 答案为零,所以SF=0
。
只是为了确认,这是一些测试代码(对于GCC):
<强> flags.c 强>
#include <stdio.h>
__attribute__((noinline))
static long test(void)
{
long ret;
asm ("mov $255, %%ah\n\t"
"mov $-1, %%al\n\t"
"cmp %%ah, %%al\n\t"
"pushf\n\t"
"pop %0\n\t"
: "=r" (ret) /* output */
: /* input */
: "%eax" /* clobber */
);
return ret;
}
static void describe_EFLAGS(long flags)
{
printf("EFLAGS: 0x%X\n", flags);
printf(" CF: %d\n", (flags & (1<<0)) > 0);
printf(" PF: %d\n", (flags & (1<<2)) > 0);
printf(" AF: %d\n", (flags & (1<<4)) > 0);
printf(" ZF: %d\n", (flags & (1<<6)) > 0);
printf(" SF: %d\n", (flags & (1<<7)) > 0);
printf(" TF: %d\n", (flags & (1<<8)) > 0);
printf(" IF: %d\n", (flags & (1<<9)) > 0);
printf(" DF: %d\n", (flags & (1<<10)) > 0);
printf(" OF: %d\n", (flags & (1<<11)) > 0);
}
int main(void)
{
long flags = test();
describe_EFLAGS(flags);
return 0;
}
<强>输出:强>
$ gcc flags.c && ./a.out
EFLAGS: 0x246
CF: 0
PF: 1
AF: 0
ZF: 1
SF: 0
TF: 0
IF: 1
DF: 0
OF: 0
<强>参考:强>
答案 1 :(得分:1)
这是我在VC 2013上运行的内容(在C ++中的警告,32位内联汇编)
在3条指令之前,标志是:
OV = 0 UP = 0 EI = 1 PL = 0 ZR = 0 AC = 0 PE = 0 CY = 0
3条指令后
OV = 0 UP = 0 EI = 1 PL = 0 ZR = 1 AC = 0 PE = 1 CY = 0
标志寄存器的位置为defined here
解释为奇偶校验集,进位未设置,零置位,未设置符号,未设置溢出。
这似乎证实了您的解决方案。 我得到的反汇编:
__asm {
mov ah, 255
00FC13CE mov ah,0FFh
mov al, -1
00FC13D0 mov al,0FFh
cmp ah, al
00FC13D2 cmp ah,al
}
我的8086非常生锈,但FWIW:
mov
在文字-1(255)和255上完成,它不会触发溢出(没有设置标志)。255
和-1
相等,则应设置零标志。所以我猜测TA可能会在某个地方粘贴错误的答案吗?