为什么AF和SF没有设置?

Why AF and SF not set?

我正在阅读 Duntemann 的书(第 3 版)并且刚刚开始学习 x86 汇编。我正在使用 Fedora 23(64 位)的变体。以下是代码:

section .data
section .text
    global  _start
_start:
    nop
; Put your experiments between the two nops...
    mov eax,0FFFFFFFFh
    mov ebx,02Dh
    dec ebx
    inc eax 
; Put your experiments between the two nops...
    nop

我的makefile如下:

sandbox: sandbox.o
    ld -o sandbox sandbox.o -melf_i386
sandbox.o: sandbox.asm
    nasm -f elf -g -F stabs sandbox.asm -l sandbox.lst

所以你可以看到我已经注意 assemble 32 位可执行文件而不是 64 位。然而,问题在于,在 dec ebx 指令之前, AFSF 标志并未设置为与书中声称的相反。 运行 insight 中的程序向我展示了 32 位寄存器,这进一步确保了可执行文件是 32 位的。以下是 gdbdec ebx 指令之前显示的状态。

(gdb) info reg
eax            0xffffffff   -1
ecx            0x0  0
edx            0x0  0
ebx            0x2d 45
esp            0xffffce80   0xffffce80
ebp            0x0  0x0
esi            0x0  0
edi            0x0  0
eip            0x804806b    0x804806b <_start+11>
eflags         0x202    [ IF ]
cs             0x23 35
ss             0x2b 43
ds             0x2b 43
es             0x2b 43
fs             0x0  0
gs             0x0  0

Duntemann 在第 217 页中的版本显示 AFSF 标志已设置。我的代码有什么问题?

正如 Margaret Bloom 评论的那样,mov 指令 没有 设置标志!事实上,它对标志绝对没有任何影响,这使得它在您想要设置寄存器或内存的内容而不破坏标志的当前状态的情况下非常有用。

the official Intel IA-32 ISA reference manual, but if you're like me, you're lazy. Fortunately, we are in luck. Several kind folks have uploaded portions of the official documentation to their websites, and these can be found easily by simply Googling "x86" plus the name of the instruction mnemonic. For example, my top result for "x86 mov" is this page 中对此进行了记录。请注意以下部分:

Flags affected
None.

当然,其他说明会在那里说不同的事情。 add 指令几乎设置了所有标志,如您所见 here.

因此,查看您的代码,执行将从标志设置为无意义的垃圾值开始。从技术上讲,它们将包含上次设置的任何值,但这在您的程序上下文中是没有意义的,因为您没有将它们设置为任何值,因此不能依赖它们被设置为有意义的值!

nopmov 指令都不会影响标志的值,因此它们将继续包含垃圾值。

在执行 dec 指令之前,标志不会包含有意义的值。然后,根据the documentation,溢出、符号、零、调整和奇偶校验标志将根据减量操作的结果设置。进位标志不受 dec 影响,因此将继续包含垃圾值。

inc instruction设置标志的方式与dec完全相同,因此溢出、符号、零、调整和奇偶校验标志将改变,但进位标志不会(和将继续包含垃圾值)。


我没有你提到的那本书的副本,所以我不知道它到底说了什么。如果它只是在代码执行的那个点显示 register/flag 状态的转储,那么标志只是垃圾值,并不重要——你应该关注寄存器中的值如何由于 mov 指令而改变。如果它实际上暗示 mov 指令设置了标志,那么这本书就有错误。 :-)