我现在正在参加大会的本科生课程。我与电讯局长分配我的任务有一些差异。我只是测试进位,零,符号和溢出标志的状态。组装状态标志8086
这里是我错了标志状态问题之一:
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
有人可以帮我确认这是正确的?我不认为我的错,但如果他们是你能解释什么答案是正确的?
我现在正在参加大会的本科生课程。我与电讯局长分配我的任务有一些差异。我只是测试进位,零,符号和溢出标志的状态。组装状态标志8086
这里是我错了标志状态问题之一:
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
有人可以帮我确认这是正确的?我不认为我的错,但如果他们是你能解释什么答案是正确的?
这里就是我得到的VC 2013(警告,32位内嵌汇编在C++)
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可能有复制粘贴错误的答案的地方?
谢谢,作业的目标是手工完成,但我很确定电讯管理局未能根据他们所在的范围和我们正在测试的国旗转换数字。显而易见,他没有用其他方法检查他的答案。 – Pixel 2014-12-08 04:25:58
您的前两个项目符号不正确。根据我的回答,'CMP'设置标志就好像执行了一个'SUB',所以如果有符号/无符号溢出,'CF'和'OF' *都可以被设置。另外,'MOV'不设置任何标志。无论如何寄存器加载指令永远不会溢出是没有意义的。 – 2014-12-08 06:12:19
谢谢 - 我的观点1确实是错误的,第二点是sl。。你的回答非常详细。 – StuartLC 2014-12-08 06:21:06
你的回答确实是对的。所述Intel Software Developer’s Manual的
卷1描述了每个标志:
CF(位0)进位标志 - 如果算术运算产生一个进位或借出most-的设置显着的结果;否则清除。该标志表示无符号整数运算的溢出条件。
ZF(位6)零标志 - 如果结果为零,则置位;否则清除。
SF(位7)符号标志 - 设置等于结果的最高有效位,即有符号整数的符号位。 (0表示正值,1表示负值)
OF(位11)溢出标志 - 如果整数结果太大,表示正数或太小表示负数(不包括符号 - 位)以适应目标操作数;否则清除。该标志表示有符号整数(二进制补码)算术的溢出条件。
比较第一源操作数与所述第二源操作数,并设置 状态标志中:
在代码的标志由
cmp
指令,其中所述指令集第2卷说设置EFLAGS根据结果注册。比较结果为 ,通过从第一个操作数中减去第二个操作数,然后以与SUB指令相同的方式设置状态标志来执行。SUB指令执行整数减法。它评估 有符号和无符号整数操作数的结果,并设置OF和CF标志以分别指示 溢出的有符号或无符号结果。 SF标志指示签名结果的标志 。
首先,我们观察到al
和ah
都具有相同的价值:所有8位1
。
由于CMP
设置了像SUB
这样的标志,因此我们只评估0xFF - 0xFF
,这当然是零。
OF,CF - 没有溢出,所以OF=0
和CF=0
。
ZF - 答案是零,所以ZF=1
。
SF - 答案是零,所以SF=0
。
只是为了确认,这里的一些测试代码(GCC):
标志。ç
#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
参考:
你的答案是正确的。如果您正在运行windows,您可以通过打开dos控制台窗口,运行debug,然后输入“a100”来手动输入指令来验证这一点:mov ah,ff | mov al,ff | cmp啊,al | nop | |,然后g = 100,106来运行代码。它将显示标志为:NV(OF = 0),...,PL(SF = 0),ZR(ZF = 1),NC(CF = 0)。输入q退出调试。如果你想知道PE是偶校验(PF = 1),PO是奇校验(PF = 0)。 –
rcgldr
2014-12-08 04:13:10