2014-12-08 45 views
2

我现在正在参加大会的本科生课程。我与电讯局长分配我的任务有一些差异。我只是测试进位,零,符号和溢出标志的状态。组装状态标志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

有人可以帮我确认这是正确的?我不认为我的错,但如果他们是你能解释什么答案是正确的?

+1

你的答案是正确的。如果您正在运行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

回答

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:

  • 这是不太可能的Sign Flag将设置给没有算术,移位或逻辑运算。查看@ Jonathon的回答。
  • mov是在文字-1(255)和255不会触发溢出(未设置标志)的文字上完成的。
  • 在一个8位寄存器中,应该设置零标志给定等于255-1

所以我猜测TA可能有复制粘贴错误的答案的地方?

+1

谢谢,作业的目标是手工完成,但我很确定电讯管理局未能根据他们所在的范围和我们正在测试的国旗转换数字。显而易见,他没有用其他方法检查他的答案。 – Pixel 2014-12-08 04:25:58

+0

您的前两个项目符号不正确。根据我的回答,'CMP'设置标志就好像执行了一个'SUB',所以如果有符号/无符号溢出,'CF'和'OF' *都可以被设置。另外,'MOV'不设置任何标志。无论如何寄存器加载指令永远不会溢出是没有意义的。 – 2014-12-08 06:12:19

+0

谢谢 - 我的观点1确实是错误的,第二点是sl。。你的回答非常详细。 – StuartLC 2014-12-08 06:21:06

2

你的回答确实是对的。所述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标志指示签名结果的标志 。

首先,我们观察到alah都具有相同的价值:所有8位1

由于CMP设置了像SUB这样的标志,因此我们只评估0xFF - 0xFF,这当然是零。

OF,CF - 没有溢出,所以OF=0CF=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 

参考: