I'm coding in x86 assembly (AT&T syntax) on 64-bit Ubuntu (so I'm using as --32
and ld -melf_i386
, which has been working fine for other exercises so far).
The jl
instruction is working opposite to what I expected. I can actually get the code to work properly with jg
, which would basically solve my problem, but I'd like to find out the underlying issue here.
The code snippet is the following:
# 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
...and the program continues, though the rest should be irrelevant for this issue.
Debugging with gdbgui, I see the open sys call returns the input file descriptor (eax = 3) without a problem.
Then you compare 0 to 3. If I'm not an idiot, 0 < 3 so the jl
instruction should take you to continue_processing
, but it does not.
However, if I instead use jg
, it works. The open sys call returns 3 in eax and jg
properly jumps to continue_processing
.
I've read that the order of the operands for jumps may depend on the assembler. Could that be the case here? Compiling with gcc -m32 -nostdlib
has the same behavior. I also tried swapping the order to cmpl %eax, $0
but I get Error: operand type mismatch for 'cmp'.
Or could it just be a quirk of the fact that this 32-bit code is being run on 64-bit Ubuntu?
I am reading the book Programming From the Ground Up. On page 125 the book example interjects a .section .data
right after the jl continue_processing
, inserts some labels and .ascii
commands, and then resumes the code with a .section .text
right before the pushl $no_open_file_msg
. To clean up the code, I've consolidated the .section .data
up on top and so do not require a second .section .text
. It doesn't seem to affect the jl
issue but I thought I'd mention it in case the problem does actually lie there.