Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 装配(或NASM)恼人的问题_Linux_Assembly_Gdb_Nasm - Fatal编程技术网

Linux 装配(或NASM)恼人的问题

Linux 装配(或NASM)恼人的问题,linux,assembly,gdb,nasm,Linux,Assembly,Gdb,Nasm,我以前使用TASM(在winXP上)编译asm代码,但我遇到了一些问题,所以现在我使用NASM(在linux上)。这段代码显示了我正在尝试做的事情: (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]

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

(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
这在我看来是正确的,但是:

我不明白为什么
al
bl
没有改变。
我确信我的代码是正确的,但是。。我想我错过了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>
80483ec:31 c9异或%ecx,%ecx
80483ee:bb 20 00 mov$0x20,%ebx
080483f3:
80483f3:8b 06 mov(%esi),%eax
80483f5:3d 00 cmp$0x0,%eax
80483fa:74 0b je 8048407
80483fc:46 inc%esi
80483fd:39 d8 cmp%ebx,%eax
80483ff:75 f2 jne 80483f3
8048401:41 inc%ecx
8048402:e9 ec ff ff jmp 80483f3

我不确定这是否是您注意到的问题,但我发现您的代码中有一个相当明显的问题。在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
寄存器中的值在此之前应已更改,但不应更新标志以反映该值


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

标志没有被mov修改,所以第34行的jz没有意义。如果您从初始的
xor
开始跟踪代码,这是唯一修改标志的指令,因此当代码到达第34行的jz时,它只是跳转(因为
xor
将其保留为零)。这并不能解释al或bl的不变值,但可能发生了一些优化,考虑到由于xor总是执行jz。

请注意,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 'ô'
,值得投赞成票

但是,我想添加一些对注释来说太长的内容:如果愿意,您可以使用在任何
显示
发生之前运行的,通过将以下内容添加到
.gdbinit
文件中,来教导
gdb
显示子寄存器:

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

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

我需要懂意大利语(大概)才能理解您的变量名吗?@Armen Tsirunyan:ups,我完全忘记了这一点。:)Edited请注意,gdb在执行指令之前会显示指令,因此您需要“stepi”或“next”来执行显示的指令。尽管如此,bl的值还是应该改变的。objdump的输出似乎表明mov是作为mov组装的,所以nasm正确地完成了它的工作。OTOH,您从objdump显示的输出与前面的源代码也不匹配。这是第二个问题,因为它们是equivalent@BlackBear:不,它们不是——objdump输出显示源代码中不存在的“cmp”(但确实解决了问题I(和@Diego)引用。我不确定你是否在以后添加了它,或者你发布的源代码可能不是我想要的。objdump的输出是我想要做的,我将修复添加cmp的源代码。但这并不能解决我的问题。问题似乎出在gdb上——你的指令显然应该修改寄存器内容,如果它没有显示t、 它有一个问题。至少从表面上看,nasm的工作是正确的。谢谢。那么问题只存在于gdb吗?我的意思是,如果我使用@Matthew Slattery的技巧,我还能使用bl和al吗?
define hook-stop
set $bl=($ebx & 0xff)
set $bh=(($ebx & 0xff00) >> 8)
set $bx=($ebx & 0xffff)
end