x86 程序集 MASM 中零标志的默认值是多少?

问题描述

例如,如果我有以下代码

L1:
        cmp WORD PTR[ebx],0
        jnz found
        add ebx,2
        loop L1
        jmp notFound

零标志的认值是否未定义?

解决方法

没有“默认值”,除非您的意思是在运行 BIOS 的第一条指令之前进行初始开机。其他任何时候,该值都是之前放置在那里的指令,就像其他寄存器一样。

如果您指的是进程的第一条用户空间指令,那将取决于内核。在调试器中尝试一下,看看您的操作系统版本会发生什么。例如,Linux 在进入用户空间之前将整数/向量寄存器清零(以避免泄漏任何内核数据),并清除 EFLAGS 中的所有条件代码标志。


像在 C 中未初始化的局部变量一样考虑寄存器(包括条件标志)。(除了 asm 没有未定义的行为;你可以读取寄存器中留下的任何以前的垃圾代码,有只是不能保证价值会是多少。)

这就是为什么这段代码在运行 cmp 之前使用 jnz 设置 FLAGS 包括 ZF,所以之前的内容无关紧要。


mul 这样留下一些标志“未定义”的指令将根据任何给定 CPU 上的某些内部条件将其设置为某个值,手册只是不保证跨不同 CPU 的任何内容。例如在某些 CPU 上,mul 可能总是清除 ZF。在其他情况下,它可能会根据低半或高半或整个事物为零而设置。 (或者它可能通常这样做,但有时不这样做,这取决于微体系结构条件。)缺乏记录的保证意味着尝试看看实际发生的事情不是一种安全的方式编写可移植的代码。

但是无论发生什么,即使在像 mul 这样的指令之后,ZF 也将是 0 或 1,并且不会在 mul 完成后例如更改几条指令。