【问题标题】:How to compare a char in a string with another char in NASM x86_64 Linux Assembly如何将字符串中的字符与 NASM x86_64 Linux 程序集中的另一个字符进行比较
【发布时间】:2016-06-25 22:27:28
【问题描述】:

我实际上是在尝试以 Intel x64 语法理解 NASM 汇编的基本概念,但在尝试制作 strchr 等效项时遇到了问题...

我一直在网上航行以获得最大的信息,但我不明白如何将字符串的当前字符(如 str[i])与简单的字符进行比较。

这是测试的主要内容:

#include <stdio.h>

extern char* my_strchr(char*, char);

int     main(void)
{
  char* str;

  str = my_strchr("foobar", 'b');
  printf("%s\n", str);
  return 0;
}

这是我的汇编代码:

我假设 rdi 是我的字符串,而 rsi 是我的单字节数据。

my_strchr:
    push    rcx                  ;Save our counter
    xor     rcx, rcx             ;Set it to 0
loop:
    cmp     rdi, byte 0          ;Check the end of string
    jz      end
    cmp     rsi, [byte rdi+rcx]  ;Here is the point ...
    jz      end
    inc     rcx                  ;increment our counter
    jmp     loop
end:
    mov     rax, [rdi+rcx]       ;Are the brackets needed ? Is it equivalent to '&' in C ? 
    pop     rcx
    ret

Gdb 给了我这个用 c 编写的 strchr 函数的输出,因此被反汇编了:

....
cmp    al,BYTE PTR [rbp-0x1c]
....

但我的实际上是这样做的:

0x400550 <my_strchr>            push   rcx
0x400551 <my_strchr+1>          xor    rcx,rcx
0x400554 <loop>                 cmp    rdi,0x0
0x400558 <loop+4>               je     0x400566 <end>
0x40055a <loop+6>               cmp    rsi,QWORD PTR [rdi+rcx*1+0x0]

提前谢谢你,希望有人知道

【问题讨论】:

    标签: linux assembly 64-bit nasm x86-64


    【解决方案1】:

    rdi 是一个指针,所以cmp rdi, 0 检查一个空指针。你的意思是cmp byte [rdi + rcx], 0 检查字符串的结尾。请注意,您需要检查当前字符,因此必须明显添加索引。

    至于 cmp rsi, [byte rdi+rcx]byte 没有任何意义,因为您正在比较整个 rsi,即 8 个字节。那应该是cmp sil, [rdi + rcx]

    最后,strchr 应该返回一个指针,所以你应该将mov rax, [rdi+rcx] 更改为lea rax, [rdi + rcx]

    【讨论】:

    • 谢谢!经过你的解释,现在一切似乎都清楚了。我刚刚发现了“lea”指令和 sil(操作数?)我应该如何知道将来何时正确使用它们呢?
    • 您可以寻址较小的寄存器部分,请参阅手册以获取名称。每当您需要更小的单元时,您就可以使用它们。 lea 对于寻址或一些简单的算术很有用。你可以对mov rax, rdi; add rax, rcx做同样的事情。
    猜你喜欢
    • 1970-01-01
    • 2016-06-30
    • 2013-01-20
    • 1970-01-01
    • 1970-01-01
    • 2020-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多