如何在NASM中进行类似于在C中完成的投射?

时间:2017-02-04 14:11:09

标签: assembly nasm

说,我已经在Assembly中定义了一个结构。我怎么能这样做?

    struct some_struct_t *s1 = (struct some_struct_t *)some_buffer;

,其中

char some_buffer[1024];
malloc = malloc(1024);
memset(some_buffer, 0, 1024);

我能想到lea或mov,但究竟是怎么回事?

1 个答案:

答案 0 :(得分:3)

考虑这个C代码(具有实现定义的行为)

void foo()
{
    struct struct1* s1 = (struct struct1*)0x01234567;  /* exp1 */
    struct struct2* s2 = (struct struct2*)0x01234567;  /* exp2 */
    struct struct3* s3 = (struct struct3*)0x01234567;  /* exp3 */
    float* f = (float*)0x01234567;                     /* exp4 */
    int* i = (int*)0x01234567;                         /* exp5 */
    char* c = (char*)0x01234567;                       /* exp6 */
}

为了清晰起见,假设s1位于[rsp-08h],则 exp1 汇总为

mov QWORD [rsp-08h], 1234567h

为了清晰起见,假设s2位于[rsp-10h],则 exp2 汇编为

mov QWORD [rsp-10h], 1234567h

为了清晰起见,假设s3位于[rsp-18h],则 exp3 汇编为

mov QWORD [rsp-18h], 1234567h

为了清晰起见,假设f位于[rsp-20h],则 exp4 汇总为

mov QWORD [rsp-20h], 1234567h

为了清晰起见,假设i位于[rsp-28h],则 exp4 汇总为

... haven't you got it yet?

组装中没有类型的东西,因此没有演员阵容 汇编中只有数据,这就是为什么我们发明了类型化的高级语言,不是if,也不是for,而是类型检查

如果您想struct some_struct_t *s1 = (struct some_struct_t *)some_buffer;,则转换为s1 = some_buffer 这只是一个价值观的分配。

现在,因为some_buffer是一个具有自动存储功能的数组,所以它转换为"它位于堆栈上#34;在x86上,您可能想知道除了(人工)演员之外,struct some_struct_t *s1 = (struct some_struct_t *)some_buffer; 的语义到底是什么,正如您现在所知,它只在编译过程中存在。

You surely know that some_buffer decay into a pointer to the first element,那么在翻译该指令时唯一要做的就是弄清楚第一个元素的地址。

好吧,我不能告诉你很多,因为我不知道你放置第一个项目的位置,但一般some_buffer是在堆栈上所以这个,一旦调整,将会做

;Compute the address of the first element
lea rax, [rsp+...]         ;or [rbp-...] if a frame pointer is available

;Store it in a local var
mov QWORD [rsp+...], rax   ;As above, also you can use any other scratch reg

使用第一个省略号代替偏移量,相对于数组第一项的rsp
第二个用于代替s1指针的偏移量。

live example see here 请注意,在该示例中,GCC在使用Red区域时过于热心,但我们可以原谅他,因为我必须禁用任何优化才能进行合理的反汇编。

如果您想知道如何为malloc执行相同操作,那么,如果您仍然不想使用godbolt.org,那么解决方案就在这里

mov edi, 1024
call malloc
mov QWORD [rsp+...], rax