Ubuntu x86组件jl不';行不通
我在64位Ubuntu上使用x86汇编(AT&T语法)进行编码(因此我使用的是Ubuntu x86组件jl不';行不通,ubuntu,assembly,x86,32-bit,att,Ubuntu,Assembly,X86,32 Bit,Att,我在64位Ubuntu上使用x86汇编(AT&T语法)进行编码(因此我使用的是as--32和ld-melf_i386,到目前为止,它在其他练习中运行良好) jl指令的工作原理与我的预期相反。实际上,我可以让代码与jg一起正常工作,这基本上解决了我的问题,但我想在这里找出根本问题 代码片段如下所示: # Open file for reading movl $SYS_OPEN, %eax # prepare syscall 5 movl $input_file_
as--32
和ld-melf_i386
,到目前为止,它在其他练习中运行良好)
jl
指令的工作原理与我的预期相反。实际上,我可以让代码与jg
一起正常工作,这基本上解决了我的问题,但我想在这里找出根本问题
代码片段如下所示:
# Open file for reading
movl $SYS_OPEN, %eax # prepare syscall 5
movl $input_file_name, %ebx # move input file name into %ebx
movl $0, %ecx # open in read-only mode
movl $0666, %edx
int $LINUX_SYSCALL # execute system call,
# sys_open returns file descriptor in %eax
movl %eax, ST_INPUT_DESCRIPTOR(%ebp) # store the input file descriptor away
# This will test and see if %eax is negative.
# If it is not negative, it will jump to continue_processing.
# Otherwise it will handle the error condition that the negative number represents.
cmpl $0, %eax
jl continue_processing
pushl $no_open_file_msg
pushl $no_open_file_code
call error_exit
continue_processing:
# Open file for writing
movl $SYS_OPEN, %eax # prepare syscall 5
…该计划仍在继续,尽管其余部分与此问题无关
使用gdbgui进行调试时,我发现opensys调用返回的输入文件描述符(eax=3)没有问题。
然后将0与3进行比较。如果我不是白痴,0<3所以jl
指令继续处理
,但是
但是,如果我改用jg
,它就可以工作了。打开系统调用并jg
至继续处理
我读过,跳跃操作数的顺序可能取决于汇编器。这里会是这样吗?使用gcc-m32-nostlib编译具有相同的行为。我还尝试将顺序交换为cmpl%eax,$0
,但出现错误:“cmp”的操作数类型不匹配
或者这可能只是因为32位代码在64位Ubuntu上运行这一事实的一个怪癖
我正在读这本书。在第125页,本书示例在jl继续处理之后插入.section.data
,插入一些标签和.ascii
命令,然后在pushl$no\u open\u file\u msg
之前插入.section.text
继续代码。为了清理代码,我将.section.data
合并在顶部,因此不需要第二个.section.text
。这似乎不会影响jl的问题,但我想我会提到它,以防问题确实存在 在AT&T语法中,与Intel语法相比,操作数的顺序是交换的。因此,
cmpl $0, %eax
实际计算eax− 0并设置标志,而不是计算0− eax正如您所期望的。因此,所有标志的设置方式都与您最初预期的相反,从而导致您观察到的问题。没有办法解决这个问题,因为它不是真的错。我建议你习惯这种怪癖
一般来说,最好使用testl
指令,而不是将值与零进行比较testl%eax,%eax
在机器代码中比cmp$0,%eax
更紧凑,在某些微体系结构上也更快。
testl
根据其操作数的位和设置标志,因此如果eax为负,则在testl%eax,%eax
之后设置SF,您可以这样检查:
testl %eax,%eax
jns continue_processing
在和之后CF=0始终。但是他可以测试SFjs阴性\u eax\u检测到的
。。。补救方法是使用英特尔语法。@Ped7g:使用JL而不是JS更有效。测试(和cmp对零)也总是清除,因此它相当于直接测试SF,但可以在更多CPU上进行宏融合。i、 e.测试%eax,%eax
/检测到jl阴性,除了AF。感谢您的确认,这很奇怪,因为这本书都是x86 AT&T汇编,作者使用了jl,我想他指的是jg。但这已经足够好了,我完全可以适应这种怪癖。@JaimeSalazar啊,这本书是从头开始编程的125@Ped7g谢谢,我混淆了CF和SF。你正在读的书是从头开始编程的(我在你的问题中添加了参考资料)。有问题的代码在第125页。这实际上是本书中的一个错误,应该是JGE
,而不是JL
。该错误已在本书的bug跟踪系统中报告。错误报告在这里:。不幸的是,这本书已经十年没有更新了。你可以在这里找到所有报告问题的列表:是的,这就是这本书。还有,很好的链接,谢谢