【问题标题】:How can i access one elemento of array in assembler如何在汇编程序中访问数组的一个元素
【发布时间】:2016-10-08 14:53:21
【问题描述】:

我需要你的帮助...实际上,我正在从事我的学术项目,并且正在努力完成它。但我不知道如何在汇编程序中访问一个数组的一个元素。

我的想法是从 C 中调用函数汇编器,同时传递参数。例如

float* calc(int n, int d, float*data){
    float* result = _mm_malloc(sizeof (float)*n*d, 16);
    calc_x86_asm(n, d, data, result)
    //Line edited, I forget to put the return
    return result; 
}

函数calc_x86_asm在文件的开头声明。

extern calc_x86_asm(int n, int d, float* data, float* result);

我的函数有以下内容:

;External asm function
extern calculate_value
section .text                   ;program
    n      equ         8
    d      equ         12
    data   equ         16
    rta    equ         20 

global calc_x86_asm    ;for linux

calc_x86_asm:
        ;Initialize a stack frame
        push    ebp
        mov     ebp, esp
        pushad
.body:
        ;Load information
        mov     ebx, [ebp+rta]
        ;Initialization counters
        xor     edx, edx
.loop:
        cmp     edx, [ebp+n]            ; if(ecx < n){
        jz      .done                   ; goto .done
                                    ; else
        push    dword [ebp+d]       ; d 
        push    dword [ebp+n]       ; n
        push    dword [edx]        ; current_row
        push    dword [ebp+data]    ; data to evaluate
        call    calculate_value
        add     esp, 16             ; restore stack after to call function.
        mov     [ebx+edx*4], eax    ;<<< Here the problem
        add     edx, 1
        jmp     .loop
.done:
        .done:
        ;Pop registries
        popad
        ;Restore the call's stack frame pointer
        pop     ebp                 ; restore ebp
        ret 

真的,我不知道我在数组内存中的赋值是否正确。因为当我运行我的项目时,应用程序会让我出错。顺便说一下,calculate_value 是一个 C 函数。

在 C 中将是这种形式:

for(int i=0; i<n; i++){
    result[i] = calc(n, d, i, data);
}

【问题讨论】:

  • 您的代码一开始就没有任何意义。你的函数没有 return 任何东西,即使它被声明为 float* calc(int n, int d, float*data)
  • 对不起,我有一个错误...我必须返回结果数组...谢谢您的评论..
  • calculate_value C 函数的原型是什么?如果它真的返回 float 值,则返回值将在数学协处理器堆栈上,而不是 EAX
  • 感谢@pcarter,计算值是一个浮点函数。在这种情况下,我必须放入哪个寄存器才能得到结果???
  • 返回值将在ST0 寄存器(数学协处理器堆栈的顶部)中。听起来您对协处理器并不熟悉。您将需要学习如何使用它。在这里解释太复杂了。谷歌是你的朋友。如果您查找 PC 汇编语言在线书籍,第 5 章介绍了协处理器。

标签: c arrays ubuntu assembly nasm


【解决方案1】:

您的问题是您在仔细设置寄存​​器后调用了 C 函数:C 函数将肯定覆盖它们。调用函数前需要保存重要的寄存器:

push ebx ; Save for later
push edx ; Save for later

push    dword [ebp+d]       ; d 
push    dword [ebp+n]       ; n
push    dword [edx]        ; current_row
push    dword [ebp+data]    ; data to evaluate
call    calculate_value
add     esp, 16             ; restore stack after to call function.

pop edx ; It's later! (Note reversed restore...)
pop ebx ; It's later!

但是这整个

  • 设置您的寄存器;
  • 保存它们
  • 呼叫C
  • 恢复寄存器
  • 返回了解更多

首先完全消除了使用汇编的需要:您不妨用 C 编写整个东西。

【讨论】:

  • 您无需在通话前后保存/恢复ebx;它已经在所有正常的 ABI 中保留了调用。最好对循环中的两个参数使用保留调用的 regs,这样您就不必在循环内使用push/pop,只需在函数的开始/结束处。 (例如,ebxesi 在我知道的所有 32 位 ABI 中都保留调用)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多