【问题标题】:Comparing struct char array with char pointer in assembly将结构字符数组与汇编中的字符指针进行比较
【发布时间】:2020-04-25 00:29:17
【问题描述】:

我正在尝试将列表中第一个结构的第一个字符与程序集中标记的第一个字符进行比较。但是,由于某种原因,这两个字符永远不会相等。我知道第一个学生的第一个字符与令牌中的第一个字符相同。

struct student
{
  long    ID;          /* 8 bytes in 64-bit */
  char    name[24];
};

/*
* list - the starting address of the list of structures to be searched
* count - total number of names in list
* token - name to be searched in the list
*/
long search_by_name (char* list, long count, char* token)
{
    long index = 0;

asm
(
    "movq %1, %%rax;" // list to rax       
    "movq %2, %%rbx;" // token to rbx
    "movq %3, %%rcx;" // count to rcx 

    "movq 8(%%rax), %%rsi;" // Offset rax by 8 to get to first char in struct
    "movq (%%rbx), %%rdi;" // Move memory address rbx into rdi
    "cmpq %%rdi, %%rsi;" // Compare the two chars
    "je equals;"         // Two chars are never equal for some reason

    "jmp finish;"

"equals:"
    "movq 0(%%rax), %%rax;"
    "jmp finish;"

"finish:"
      : "=a" (index)
     : "r" (list), "r" (token), "r" (count)
     : 
     );
     return index;
}
What it's supposed to do in C:

struct student *clist = (struct student*)list;
for (index = 0; index < count; index++)  
    if ( strcasecmp( clist[index].name, token ) == 0)
        return clist[index].ID;
return 0;

最终结果应该是 C 代码,但我仍在尝试弄清楚如何比较 clist[index].nametoken。 如何将 struct char 数组与令牌 char* 进行比较?

编辑: 将其更改为:

movq 8(%%rax), %%r10; 
movq (%%rbx), %%r11; 
cmpb %%r10b, %%r11b;

【问题讨论】:

  • 为什么listchar* 而不是struct student*?你调用search_by_name的代码在哪里?
  • list 是一个指向结构数组的char*,而search_by_name 在主方法中调用的时间过长,无法在此处发布。您可以假设 main 方法按预期工作。唯一的问题是将char* list 中第一个student 的第一个字符与char* token 进行比较。
  • 您的 asm 语句没有在您选择的任何硬编码寄存器上声明 clobber("=a" 输出除外),也没有 "memory" clobber 告诉编译器内存指向- to by input 操作数也是一个输入。 How can I indicate that the memory *pointed* to by an inline ASM argument may be used?.
  • 实际的 asm 看起来也有问题:cmets 说“比较两个字符”,但实际上您已经从每个字符中加载了 8 个字节的 char 数据。如果您使用调试器单步执行代码并查看寄存器,这将是显而易见的。此外,您可以将je equals 简化为只使用jne finish 而不是跳过jmp
  • 你能用纯 C 写search_by_name,然后把它编辑成你的问题吗?这可能会让你更清楚你的目标。

标签: assembly x86-64 inline-assembly


【解决方案1】:

两个主要问题:首先,cmpq 比较前 8 个字符,而不仅仅是一个。其次,当比较失败时,您返回指针list,而不是任何类型的哨兵。

此外,您正在破坏一堆寄存器,但没有让 GCC 知道。在您最后一个: 之后,添加"rbx", "rcx", "rsi", "rdi", "cc", "memory"

【讨论】:

  • 我返回指针list,因为它指向list 中的第一个结构。它只是一个占位符,直到我弄清楚如何将第一个结构中的 char[]char* token 进行比较。
  • 我接受了你所说的 cmpq 如何比较前 8 个字符,在查看了我的笔记后,我将其更改为比较字节 0。将其更改为:movq 8(%%rax), %%r10; movq (%%rbx), %%r11; cmpb %%r10b, %%r11b;
猜你喜欢
  • 1970-01-01
  • 2022-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-17
  • 1970-01-01
  • 2021-04-02
相关资源
最近更新 更多