x86 Assembly-在遍历数组并设置等于数组中元素的变量时陷入困境

时间:2019-02-04 15:26:37

标签: assembly x86 x86-64 intel gas

只想从一个警告开始,即我通常是汇编语言的新手。我正在尝试使用循环遍历数组,同时还将数组中的元素分配给变量。我已经输入了c ++的实现方式,但是当涉及到将其转换为程序集时,我完全迷失了,在网上找不到任何有用的东西。

这是怎么回事,我正在遍历其中包含16个元素的数组,但是我需要一次访问4个元素,以便有重叠。因此,当i = 12时,它将访问数组元素array [12],... array [15]。

for (int i = 0; i < 13; i++)
{
    w = array[i];
    x = array[i+1];
    y = array[i+2];
    z = array[i+3];

    result = function(w, x, y, z);
    // output
}

int function (int w, int x, int y, int z)
{
    return (w-x)*(y+z);
}

这就是我要的汇编代码。几乎只不过是它的外壳,但是当涉及到分配变量时,我有点迷茫。

loop:
    cmp %13, %rcx


    call myfunction /* insert function call to perform a computation on all 4 variables */
    /* insert call to output the variables with the result of the computation */

    inc %rcx
    jmp loop

1 个答案:

答案 0 :(得分:0)

这里是简化的程序集(这里可以进行很多优化,但是会使代码复杂化),为此我使用了与GCC相同的调用约定:

function:
  /* save the old stack frame*/
  push rbp
  mov rbp, rsp

  /* w, x, y, z = rdi, rsi, rdx, rcx */
  sub edi, esi /* edi -= esi */
  add edx, ecx /* edx -= ecx */
  imul edi, edx /* edi *= edx */

  /* Conclude the call */
  mov eax, edi /* return value */
  mov rsp, rbp
  pop rbp
  ret

/*main_logic(array)*/
main_logic:
  /* save the old stack frame*/
  push rbp
  mov rbp, rsp

  /* rdi contains the pointer to the array, save it*/
  mov r8, rdi

  /* r9 = 0 */
  xor r9, r9

  calc_loop:
    /* We're using the e registers because ints in C are 4 bytes */
    /* e registers are subregisters of r registers with similar names that refer to the first 4 bytes of the register */
    /* r registers are 8 bytes */
    mov edi, [r8+r9*4] /* r8[r9] */
    mov esi, [r8+r9*4+4] /* r8[r9+1] */
    mov edx, [r8+r9*4+8] /* r8[r9+2] */
    mov ecx, [r8+r9*4+12] /* r8[r9+3] */
    call fn /* result = function(w, x, y, z); */

    mov edi, eax /*Pass return value of function to output function*/
    /*call your number outputting function here*/

    inc r9 /* r9 ++ */
    cmp r9, 14 /* r9 < 14 */
    jne calc_loop /* Jump back to the beginning of the calc_loop */

  /* Conclude the call */
  mov rsp, rbp
  pop rbp
  ret