Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assembly (or NASM) annoying problem

I used to compile my asm code with TASM (on winXP) but I had some troubles so now I use NASM (on linux). This snippet shows what I'm trying to do:

(gdb) list 35
30      xor ecx,ecx             # ecx is a counter
31      mov bl, ' '             # this is what I'm looking for
32  count_spaces:
33      mov al,[esi]            # grab a char
34      jz  spaces_counted      # is this the end?
35      inc esi                 # next char
36      cmp al,bl               # found one?
37      jne count_spaces        # nope, loop
38      inc ecx                 # yep, inc counter
39      jmp count_spaces        # and loop

This looks correct to me, but:

Breakpoint 1, main () at project1.asm:30
30      xor ecx,ecx
(gdb) display (char) $al
1: (char) $al = 0 '\000'
(gdb) display (char) $bl
2: (char) $bl = 0 '\000'
(gdb) next
31      mov bl, ' '
2: (char) $bl = 0 '\000'
1: (char) $al = 0 '\000'
(gdb) 
count_spaces () at project1.asm:33
33      mov al,[esi]
2: (char) $bl = 0 '\000'
1: (char) $al = 0 '\000'
(gdb) 

I can't understand why al and bl didn't change.
I'm sure my code is correct, but.. I think I missed some NASM's option? BTW I compiled with

nasm -f elf -l project1.lst -o project1.o -i../include/ -g  project1.asm

After compiling, I disassembled the output and got:

 80483ec:   31 c9                   xor    %ecx,%ecx
 80483ee:   bb 20 00 00 00          mov    $0x20,%ebx

080483f3 <count_spaces>:
 80483f3:   8b 06                   mov    (%esi),%eax
 80483f5:   3d 00 00 00 00          cmp    $0x0,%eax
 80483fa:   74 0b                   je     8048407 <spaces_counted>
 80483fc:   46                      inc    %esi
 80483fd:   39 d8                   cmp    %ebx,%eax
 80483ff:   75 f2                   jne    80483f3 <count_spaces>
 8048401:   41                      inc    %ecx
 8048402:   e9 ec ff ff ff          jmp    80483f3 <count_spaces>
like image 233
BlackBear Avatar asked Dec 06 '22 22:12

BlackBear


2 Answers

Note that GDB doesn't know about the 8 or 16 bit aliased registers. It will always print 0 for al, bl, ax, bx, etc. You should use eax, ebx, etc:

(gdb) info registers bl
Invalid register `bl'
(gdb) info registers bx
Invalid register `bx'
(gdb) info registers ebx
ebx            0xf7730ff4       -143454220
(gdb) p $bl
$1 = void
(gdb) p $bx
$2 = void
(gdb) p $ebx
$3 = -143454220
(gdb) p/x $bl
$4 = Value can't be converted to integer.
(gdb) p/x $bx
$5 = Value can't be converted to integer.
(gdb) p/x $ebx
$6 = 0xf7730ff4
(gdb) p (char) $bl
$7 = 0 '\0'
(gdb) p (char) $bx
$8 = 0 '\0'
(gdb) p (char) $ebx
$9 = -12 'ô'
like image 70
Jester Avatar answered Dec 15 '22 00:12

Jester


Jester has the right answer, and deserves an up-vote.

But, I'd like to add something which is too long for a comment: you can teach gdb to display sub-registers if you wish, using the hook-stop hook, which runs just before any display happens, by adding the following to your .gdbinit file:

define hook-stop
set $bl=($ebx & 0xff)
set $bh=(($ebx & 0xff00) >> 8)
set $bx=($ebx & 0xffff)
end

(extend in the obvious way for other registers). display $bl etc. will then work as you expect.

like image 28
Matthew Slattery Avatar answered Dec 15 '22 01:12

Matthew Slattery