简体   繁体   English

为什么没有设置AF和SF?

[英]Why AF and SF not set?

I'm reading Duntemann's book (3rd edition) and have just started learning x86 assembly. 我正在阅读Duntemann的书(第3版),并且刚刚开始学习x86汇编。 I'm using a variant of Fedora 23 (64 bit). 我正在使用Fedora 23(64位)的变体。 The following is the code: 以下是代码:

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

My makefile is as follows: 我的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

So you can see I've taken care to assemble a 32bit executable and not 64bit. 因此,您可以看到我很小心地组装了32位可执行文件,而不是64位。 The problem, however, is that prior to dec ebx instruction the AF and SF flag is not set contrary to what the book claimed. 但是,问题在于,在dec ebx指令之前, AFSF标志的设置与本书所声称的相反。 Running the program in insight shows me 32 bit registers which further assures the executable is 32bit. insight运行该程序可以看到32位寄存器,这进一步确保了可执行文件是32位。 The following is status shown by gdb just before dec ebx instruction. 以下是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's version in Pg 217 shows that AF and SF flag is set. 第217页的Duntemann版本显示已设置AFSF标志。 What is wrong with my code? 我的代码有什么问题?

As Margaret Bloom commented, the mov instruction does not set the flags! 正如玛格丽特·布鲁姆(Margaret Bloom)所说, mov指令设置标志! In fact, it has absolutely no effect on the flags whatsoever, which makes it very useful in cases where you want to set the contents of a register or memory without clobbering the current state of the flags. 实际上,它绝对不会对标志产生任何影响,这在想要设置寄存器或存储器的内容而又不会破坏标志的当前状态的情况下非常有用。

This is documented in the official Intel IA-32 ISA reference manual , but if you're like me, you're lazy. 这在正式的Intel IA-32 ISA参考手册中有所记录,但是如果您像我一样,那就很懒。 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. 好几种人已经将官方文档的一部分上载到了他们的网站上,而您可以通过简单地使用Google的“ x86”加上指令助记符的名称来轻松找到这些文件。 For example, my top result for "x86 mov" is this page . 例如,对于“ x86 mov”,我的最高搜索结果是此页面 Note the following section: 请注意以下部分:

Flags affected 标志受影响
None. 没有。

Other instructions will say different things there, of course. 当然,其他说明会在那说不同的话。 The add instruction sets virtually all of the flags, as you can see here . add指令集几乎所有的标志,你可以看到在这里

So, looking at your code, execution will begin with the flags set to meaningless, garbage values. 因此,查看您的代码,执行将从标志设置为无意义的垃圾值开始。 Technically, they will contain whatever values they were last set to, but this is meaningless in the context of your program, because you did not cause them to be set to anything, and therefore cannot rely on them being set to meaningful values! 从技术上讲,它们将包含上次设置的值,但这在程序上下文中是没有意义的,因为您没有将它们设置为任何值,因此不能依赖于将它们设置为有意义的值!

Neither the nop nor the mov instructions will affect the values of the flags, so they will continue to contain garbage values. nopmov指令都不会影响标志的值,因此它们将继续包含垃圾值。

The flags will not contain meaningful values until the dec instruction is executed. 在执行dec指令之前,这些标志将不包含有意义的值。 Then, as per the documentation , the overflow, sign, zero, adjust, and parity flags will be set according to the result of the decrement operation. 然后,根据文档 ,将根据减量操作的结果设置溢出,正负号,零,调整和奇偶校验标志。 The carry flag is not affected by dec and will therefore continue to contain a garbage value. 进位标志不受dec影响,因此将继续包含垃圾值。

The inc instruction sets the flags in exactly the same way as dec , so the overflow, sign, zero, adjust, and parity flags will change, but the carry flag will not (and will continue to contain a garbage value). inc指令以与dec完全相同的方式设置标志,因此溢出,符号,零,调整和奇偶校验标志将更改,但进位标志不会更改(并将继续包含垃圾值)。


I don't have a copy of the book you reference, so I don't know what it actually says. 我没有您所参考的书的副本,所以我不知道它的实际含义。 If it's just showing a dump of the register/flag state at that point in the code's execution, then the flags are just garbage values and not intended to be significant—you're supposed to focus on how the values in the registers have changed as a result of the mov instruction(s). 如果只是在执行代码的那一刻显示寄存器/标志状态的转储,则标志只是垃圾值,而不是有意义的-您应该集中精力研究寄存器中的值如何更改为mov指令的结果。 If it is actually implying that the mov instruction sets the flags, well, then the book has a bug. 如果实际上暗示mov指令设置了标志,那么这本书有一个错误。 :-) :-)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM