【问题标题】:Assembly (or NASM) annoying problem装配(或 NASM)烦人的问题
【发布时间】:2011-07-09 22:26:47
【问题描述】:

我以前用 TASM(在 winXP 上)编译我的 asm 代码,但我遇到了一些麻烦,所以现在我使用 NASM(在 linux 上)。这个 sn-p 显示了我正在尝试做的事情:

(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

这在我看来是正确的,但是

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) 

我不明白为什么 albl 没有改变。
我确定我的代码正确的,但是.. 我想我错过了一些 NASM 的选项? 顺便说一句,我用

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

编译后反汇编输出得到:

 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>

【问题讨论】:

  • 我需要懂意大利语(大概)才能理解你的变量名吗?
  • @Armen Tsirunyan: ups,我完全忘记了。 :) 已编辑
  • 请注意,gdb 会在执行它们之前显示指令,因此您需要“stepi”或“next”来执行显示的指令。不过,bl 的值应该已经改变了。

标签: linux assembly gdb nasm


【解决方案1】:

请注意,GDB 不知道 8 位或 16 位别名寄存器。 al, bl, ax, bx 等总是会打印 0。你应该使用 eax, ebx 等:

(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 'ô'

【讨论】:

  • 谢谢。那么问题仅与gdb有关吗?我的意思是,如果我使用@Matthew Slattery 的技巧,我还能使用 bl 和 al 吗?
【解决方案2】:

Jester has the right answer,值得一票。

但是,我想添加一些太长的评论:如果你愿意,你可以教gdb 显示子寄存器,使用hook-stop hook,它在任何display 发生之前运行, 通过将以下内容添加到您的 .gdbinit 文件中:

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

(以明显的方式扩展其他寄存器)。 display $bl 等将按照您的预期工作。

【讨论】:

    【解决方案3】:

    我不确定这是否是您提到的问题,但我在您的代码中看到了一个相当明显的问题。在 x86 上,mov 确实 影响标志。你的代码:

    33      mov al,[esi]            # grab a char
    34      jz  spaces_counted      # is this the end?
    

    似乎假设当您从[esi] 加载al 时,z 标志将被更新以反映 al 的内容。 不是的情况。要测试你刚刚加载的值是否为零,你需要添加一个显式测试:

    mov al, [esi]
    test al, al
    jz spaces_counted
    

    in 寄存器的值之前应该已经改变,但标志应该 已经更新以反映该值。

    至于 nasm 是否产生了正确的指令,我会反汇编代码来看看到底有什么。现在,很难猜测问题出在 nasm 还是 gdb 上。当然,反汇编程序也不能保证没有错误,但看到这么简单的代码出现问题,我会有点惊讶。

    【讨论】:

    • objdump 的输出似乎表明 mov 是作为 mov 组装的,所以 nasm 正确地完成了它的工作。 OTOH,您从 objdump 显示的输出确实 与它之前的源代码匹配。
    • 这是次要问题,因为它们是等价的
    • @BlackBear:不,它们不是——objdump 输出显示源代码中不存在的“cmp”(但确实解决了我(和@Diego)引用的问题。我'我不确定你是不是后来添加的,或者你发布的源代码不是预期的。
    • objdump 的输出是我想要做的,我将修复我的源添加该 cmp。但这并不能解决我的问题
    • 看起来问题出在 gdb 上——你的指令显然应该修改寄存器内容,如果没有显示,那就有问题。至少从表面上看,nasm 做得很好。
    【解决方案4】:

    flags 没有被 mov 修改,所以第 34 行的 jz 没有意义。如果您遵循初始 xor 中的代码,那是修改标志的唯一指令,因此当代码到达第 34 行的 jz 时,它只会跳转(因为 xor 将其设为零)。这并不能解释 al 或 bl 的不变值,但可能进行了一些优化,考虑到 jz 总是因为 xor 而执行。

    【讨论】:

      猜你喜欢
      • 2011-01-15
      • 1970-01-01
      • 2021-12-04
      • 1970-01-01
      • 2014-03-07
      • 1970-01-01
      • 1970-01-01
      • 2012-08-16
      • 2011-07-12
      相关资源
      最近更新 更多