为什么没有设置AF和SF?

May*_*rma 0 x86 assembly x86-64 nasm

我正在阅读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
Run Code Online (Sandbox Code Playgroud)

我的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
Run Code Online (Sandbox Code Playgroud)

所以你可以看到我已经注意组装一个32位可执行文件,而不是64位.然而,问题在于,在dec ebx指令之前,AF并且SF没有设置标志与书所声称的相反.运行该程序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
Run Code Online (Sandbox Code Playgroud)

Punte 217中的Duntemann版本显示AFSF设置了标志.我的代码出了什么问题?

Cod*_*ray 5

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

这在英特尔IA-32 ISA官方参考手册中有记载,但如果你像我一样,那你很懒.幸运的是,我们很幸运.有几种人将官方文档的部分内容上传到他们的网站,只需使用Google搜索"x86"加上指令助记符的名称即可轻松找到这些文档.例如,我对"x86 mov"的最高结果就是这个页面.请注意以下部分:

受影响的标志
无.

当然,其他说明会说不同的东西.该add指令集几乎所有的标志,你可以看到在这里.

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

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

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

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


我没有你所引用的书的副本,所以我不知道它实际上是什么.如果它只是在代码执行中的那一点显示寄存器/标志状态的转储,那么标志只是垃圾值而不是重要的 - 你应该关注寄存器中的值如何变化为mov指令的结果.如果它实际上暗示mov指令设置了标志,那么这本书就有一个错误.:-)

  • 好吧,它们对你来说很垃圾.无论你之前执行的代码是什么,都不会认为它们是垃圾.没有指令实际上将它们设置为垃圾. (2认同)