【发布时间】:2018-05-24 23:45:09
【问题描述】:
我在 64 位 Ubuntu 上使用 x86 程序集(AT&T 语法)进行编码(所以我使用的是 as --32 和 ld -melf_i386,到目前为止,它在其他练习中运行良好)。
jl 指令的工作方式与我的预期相反。我实际上可以让代码与jg 一起正常工作,这基本上可以解决我的问题,但我想在这里找出根本问题。
代码sn-p如下:
# 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 进行调试,我看到 open sys 调用返回输入文件描述符 (eax = 3) 没有问题。
然后你比较 0 和 3。如果我不是白痴,0 jl 指令should take you to continue_processing,但it does not。
但是,如果我改用jg,它就可以工作。打开系统调用returns 3 in eax 和jg properly jumps 到continue_processing。
我读过跳转操作数的顺序可能取决于汇编程序。这里会是这样吗?使用gcc -m32 -nostdlib 编译具有相同的行为。我还尝试将订单交换为cmpl %eax, $0,但出现错误:'cmp' 的操作数类型不匹配。
或者这只是这个 32 位代码在 64 位 Ubuntu 上运行这一事实的怪癖?
我正在看书Programming From the Ground Up。在第 125 页上,本书的示例在 jl continue_processing 之后插入了 .section .data,插入了一些标签和 .ascii 命令,然后在 pushl $no_open_file_msg 之前使用 .section .text 恢复代码。为了清理代码,我将.section .data 合并到顶部,因此不需要第二个.section .text。它似乎不会影响jl 问题,但我想我会提到它,以防问题确实存在。
【问题讨论】:
-
您正在阅读的书是从头开始编程(我在您的问题中添加了参考)。有问题的代码在第 125 页。这实际上是书中的一个错误,它应该是
JGE而不是JL。该错误已在本书的错误跟踪系统中报告。该错误报告在这里:savannah.nongnu.org/bugs/?17654。不幸的是,这本书已经十年没有更新了。您可以在此处找到所有已报告问题的列表:savannah.nongnu.org/bugs/?group=pgubook -
是的,就是这本书。另外,很好的链接,谢谢
标签: ubuntu assembly x86 32-bit att