【问题标题】:C struct to complete assembly code for functionC struct 完成函数的汇编代码
【发布时间】:2015-04-27 13:56:17
【问题描述】:

我得到了以下代码框架:

typedef struct node {
    _______________ x;
    _______________ y;
    struct node *next;
    struct node *prev;
} node_t;

node_t n;
void func() {
    node_t *m;
    m = ______________________;
    m->y /= 16;
    return; 
}

在 IA-32 linux 机器上生成以下汇编代码:

func:
  pushl %ebp
  movl n+12,%eax
  movl 16(%eax),%eax
  movl %esp,%ebp
  movl %ebp,%esp
  shrw $4,8(%eax)
  popl %ebp
  ret

我需要填写上面的空白。我确实相信,当我看到他的台词时:

m->y /= 16; and shrw $4,8(%eax)

这显然是 node_t *m 的第 8 个字节的右移。所以我认为在 y 之前有 8 个字节,所以 x 是 8 个字节长(双)。另外,我认为 struct 'node' 的总大小来自行

movl n+12, %eax

因为这是创建 node_t *m 的地方。我只是不确定如何从该行确定它的大小。

我也提供了这个信息

还应注意,指针的大小和对齐方式为 4 个字节。

【问题讨论】:

  • @T.C.感谢您指出了这一点。我编辑了它。
  • shrw $4, 8(%eax) 表明m->yunsigned short。有符号值通常使用sar(算术右移)。
  • @BrettHale 是因为它是单词后面的 w 吗?意思是两个字节?
  • @scottybobby - 你明白了。 bwlq 为 1、2、4、8 个字节。
  • 您获得的表格不包括指针的大小和对齐方式(例如 struct node *)。

标签: c assembly struct reverse-engineering


【解决方案1】:

在 32 位模式下,指针为 4 字节,通常在 4 字节边界上对齐。所以n + 12 实际上是将& n.next 加载到%eax。例如,如果y 一个unsigned short,那么next之前的结构中有2个字节的填充。

movl 16(%eax),%eax 使用 16 字节的偏移量解除引用,给出:m = n.next->prev


struct node
{
    double x;          /* bytes: 0  .. 7  */
    unsigned short y;  /* bytes: 8  .. 9  */
                       /* bytes: 10 .. 11 */ /* (padding) */
    struct node *next; /* bytes: 12 .. 15 */
    struct node *prev; /* bytes: 16 .. 19 */
};

【讨论】:

  • n+12 表示他们从 n 跳了 12 个字节?所以 x 和 y 加起来有 12 个字节长,对吗?
  • @T.C. - 发现。 x 也可能是 64 位的 [unsigned] long long(或者在 LP64 平台上只是 long),但这里没有作为选项给出。 node 结构体共有 20 个字节。
  • 下一个指针 -> 4Bytes,上一个指针 -> 4Bytes,还有其他?那 12 个字节是如何共享的?你将如何填写变量 x 和 y 的类型?
  • @BrettHale 我不完全确定你是如何得到 m = n.next->prev 的。我不知道您在取消引用时如何计算 16 个字节。
  • @scottybobby - movl (%eax), %eax 将“加载”由n.next指向的节点的前 4 个字节。 16 字节偏移量从第 16 个字节开始加载 4 个字节,即n.next->prev
猜你喜欢
  • 1970-01-01
  • 2014-11-30
  • 2021-07-18
  • 2012-03-04
  • 2013-04-20
  • 2018-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多