c - 使用 GNU 程序集访问指向结构的 *next 指针

标签 c assembly struct gnu gnu-assembler

我正在使用 GNU 程序集尝试遍历一个 C 结构链接列表并从其中一个结构值中找到某个值。我想知道如何到达结构的 *next 指针以移动到下一个节点并检查值。下面是我编写的一些示例 C 代码,用于尝试和学习。

struct node{
   struct node *next;
   int id;
  };

struct node *root;

void functionToBuildLinkList(){
   //Code to malloc and link 4 nodes
 }

int main(int argc, char *argv[]){

   functionToBuildLinkList();

   int valueOne;

   rootPtr = rootPtr->next;
   valueOne = rootPtr->id;
   printf("The valueOne is: %i\n", valueOne);

   return 0;
}

为了尝试帮助自己弄清楚,我查看了 main 的 objdump。

mov    0x804a024,%eax   //Moving the rootPtr->next address into eax
mov    0x4(%eax),%eax   //Offset 4 bytes for id
mov    %eax,0x804a024   //Compiler nonsense?
mov    0x804a024,%eax   //Compiler nonsense?
mov    (%eax),%eax      //Moving the contents of EAX into EAX or more nonsense?
mov    %eax,0x1c(%esp)  //Moving id into the stack
mov    $0x804861c,%eax  //What address is being moved into EAX?
mov    0x1c(%esp),%edx  //Moving id into edx
mov    %edx,0x4(%esp)   //Moving edx (id) into the stack
mov    %eax,(%esp)      //What's the address in EAX? The top of stack - ESP?
call   8048340 <printf@plt>
mov    $0x0,%eax        //Returning O

我有点不高兴,因为看起来编译器正在提供硬编码的内存地址。我怎么知道下一个或某些节点所在的内存地址?当我通过在堆上分配内存来创建列表时,它是按顺序排列的,所以我可以尝试用这种方式计算出来吗?我将如何完成列表?此外,*next 指针是第一个成员变量,当我将内存地址获取到结构的开头时,它不会有偏移量(访问它)吗?感谢您的帮助。

感谢大家的帮助!因此,使用示例代码中的全局指针 root 遍历列表将是:

movl root, %eax   //Move root into EAX
movl (%eax), %eax //eax = eax->next

最佳答案

有两种不同的寻址方式:

mov    0x804a024,%eax   //Moving the rootPtr (content) into eax
mov    [%eax], %ebx     //access tmp=rootPtr->next

add    0x4, %ebx        // increment tmp by 4 to get the address of &tmp->id

mov    $0x804861c,%eax  // Moving an address to eax

第一行通常写成

mov.l  [0x804a024], %eax

第一个“废话”对应赋值的左边

rootPtr = rootPtr->next;

虽然下一行可以优化掉。

关于c - 使用 GNU 程序集访问指向结构的 *next 指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12766188/

相关文章:

c - 递增指向数组的指针

c - 如何检测或测试用于 USB 闪存驱动器插入的 unix/linux 开发节点创建

assembly - 在 MIPS 汇编中,如果浮点寄存器中有浮点值 X.YZDEF,如何截断到小数点后两位?

c# - 是否可以从 List<T> 访问结构体的引用来进行更改?

c - 用于密码的 PBKDF2-HMAC-SHA1——C 中的示例?

c - 如何解决C中的默认垃圾值?

assembly - 为什么 `add cl, 2` 以 x86 十六进制打印 `80 c1 02`?

assembly - Commodore基本4套路

pointers - 如何将 Rust 结构的引用/指针传递给 C ffi 接口(interface)?

pointers - Go结构指针不是唯一的