将 C 代码转换为数组的程序集
Converting c code into assembly for arrays
我目前正在学习如何将 C 代码转换为汇编 x86 64 位代码。我的代码是:
long add_arrays(long *arr1, long *arr2, unsigned long num, long *result)
{
unsigned long sum = 0, i = 0;
while(i < num) {
result[i] = arr1[i] + arr2[i];
sum = sum + result[i];
i++;
}
return sum;
}
当我将它转换为汇编时,我得到的输出是 0 或地址编号。我的代码是:
.global add_arrays_asm
add_arrays_asm:
xor %r8, %r8
while_start:
cmp %r8, %rdx
jge while_break
movq (%rdi, %r8, 8), %r9
addq (%rsi, %r8, 8), %r9
movq (%rcx, %r8, 8), %r10
movq (%r9, %r8, 8), %rcx
addq (%r10, %r8, 8), %rax
addq (%rcx,%r8, 8), %rax
inc %r8
jmp while_start
while_break:
ret
我用来测试它的代码是:
printf("Testing add_arrays_asm\n");
long l3[] = {3, 23, 32, 121, 0, 43, 95, 4};
long l4[] = {-823,12,-1222,84834, -328, 0, 9, -1387};
long res1[] = {0, 0, 0, 0, 0, 0, 0, 0};
long sum1 = add_arrays_asm(l3, l4, 8, res1);
int j = 0;
for(j = 0; j < 8; j++) {
printf("%8ld + %8ld = %8ld\n", l3[j], l4[j], res1[j]);
}
printf(" Sum = %ld\n\n", sum1);
我不熟悉汇编代码,所以我找不到代码哪里出错了。任何帮助,将不胜感激。谢谢。
你的条件跳转不正确。
cmp %r8, %rdx
jge while_break
这意味着
if (rdx >= r8)
break;
所以你什么都不计算就直接break了循环。此外,您应该使用 jae
而不是 jge
进行无符号比较,因为您将其声明为 unsigned long num
。尽管如果该值没有溢出最大有符号整数以至于它为负数,这可能不是问题。
另一件事,您的加载和存储似乎不正确。除此之外,您最好将内存访问保持在最低限度,如果您真的不需要它,则无需从内存中重新加载。
此外,您忘记将 %rax
归零,您应该在计算开始时有 sum = 0
。
解决这个问题
我修改了你的汇编代码。
func.S
.section .text
.global add_arrays_asm
add_arrays_asm:
#rdi -> arr1
#rsi -> arr2
#rdx -> num
#rcx -> result
#r8 -> i
xorl %r8d, %r8d # i = 0
xorl %eax, %eax # sum = 0
while_start:
cmpq %rdx, %r8 # if (i >= num)
jae while_break # goto while_break
movq (%rdi, %r8, 8), %r9 # r9 = arr1[i]
addq (%rsi, %r8, 8), %r9 # r9 += arr2[i]
movq %r9, (%rcx, %r8, 8) # result[i] = r9
addq %r9, %rax # sum += r9
incq %r8 # i++
jmp while_start # goto while_start
while_break:
ret
main.c
#include <stdio.h>
long add_arrays_asm(long *arr1, long *arr2, unsigned long num, long *result);
int main()
{
printf("Testing add_arrays_asm\n");
long l3[] = {3, 23, 32, 121, 0, 43, 95, 4};
long l4[] = {-823,12,-1222,84834, -328, 0, 9, -1387};
long res1[] = {0, 0, 0, 0, 0, 0, 0, 0};
long sum1 = add_arrays_asm(l3, l4, 8, res1);
int j = 0;
for(j = 0; j < 8; j++) {
printf("%8ld + %8ld = %8ld\n", l3[j], l4[j], res1[j]);
}
printf(" Sum = %ld\n\n", sum1);
}
执行
ammarfaizi2@integral:/tmp/testz$ gcc -Wall -Wextra func.S main.c -o main
ammarfaizi2@integral:/tmp/testz$ valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./main
==748530== Memcheck, a memory error detector
==748530== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==748530== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==748530== Command: ./main
==748530==
Testing add_arrays_asm
3 + -823 = -820
23 + 12 = 35
32 + -1222 = -1190
121 + 84834 = 84955
0 + -328 = -328
43 + 0 = 43
95 + 9 = 104
4 + -1387 = -1383
Sum = 81416
==748530==
==748530== HEAP SUMMARY:
==748530== in use at exit: 0 bytes in 0 blocks
==748530== total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
==748530==
==748530== All heap blocks were freed -- no leaks are possible
==748530==
==748530== For lists of detected and suppressed errors, rerun with: -s
==748530== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
ammarfaizi2@integral:/tmp/testz$
我目前正在学习如何将 C 代码转换为汇编 x86 64 位代码。我的代码是:
long add_arrays(long *arr1, long *arr2, unsigned long num, long *result)
{
unsigned long sum = 0, i = 0;
while(i < num) {
result[i] = arr1[i] + arr2[i];
sum = sum + result[i];
i++;
}
return sum;
}
当我将它转换为汇编时,我得到的输出是 0 或地址编号。我的代码是:
.global add_arrays_asm
add_arrays_asm:
xor %r8, %r8
while_start:
cmp %r8, %rdx
jge while_break
movq (%rdi, %r8, 8), %r9
addq (%rsi, %r8, 8), %r9
movq (%rcx, %r8, 8), %r10
movq (%r9, %r8, 8), %rcx
addq (%r10, %r8, 8), %rax
addq (%rcx,%r8, 8), %rax
inc %r8
jmp while_start
while_break:
ret
我用来测试它的代码是:
printf("Testing add_arrays_asm\n");
long l3[] = {3, 23, 32, 121, 0, 43, 95, 4};
long l4[] = {-823,12,-1222,84834, -328, 0, 9, -1387};
long res1[] = {0, 0, 0, 0, 0, 0, 0, 0};
long sum1 = add_arrays_asm(l3, l4, 8, res1);
int j = 0;
for(j = 0; j < 8; j++) {
printf("%8ld + %8ld = %8ld\n", l3[j], l4[j], res1[j]);
}
printf(" Sum = %ld\n\n", sum1);
我不熟悉汇编代码,所以我找不到代码哪里出错了。任何帮助,将不胜感激。谢谢。
你的条件跳转不正确。
cmp %r8, %rdx
jge while_break
这意味着
if (rdx >= r8)
break;
所以你什么都不计算就直接break了循环。此外,您应该使用 jae
而不是 jge
进行无符号比较,因为您将其声明为 unsigned long num
。尽管如果该值没有溢出最大有符号整数以至于它为负数,这可能不是问题。
另一件事,您的加载和存储似乎不正确。除此之外,您最好将内存访问保持在最低限度,如果您真的不需要它,则无需从内存中重新加载。
此外,您忘记将 %rax
归零,您应该在计算开始时有 sum = 0
。
解决这个问题
我修改了你的汇编代码。
func.S
.section .text
.global add_arrays_asm
add_arrays_asm:
#rdi -> arr1
#rsi -> arr2
#rdx -> num
#rcx -> result
#r8 -> i
xorl %r8d, %r8d # i = 0
xorl %eax, %eax # sum = 0
while_start:
cmpq %rdx, %r8 # if (i >= num)
jae while_break # goto while_break
movq (%rdi, %r8, 8), %r9 # r9 = arr1[i]
addq (%rsi, %r8, 8), %r9 # r9 += arr2[i]
movq %r9, (%rcx, %r8, 8) # result[i] = r9
addq %r9, %rax # sum += r9
incq %r8 # i++
jmp while_start # goto while_start
while_break:
ret
main.c
#include <stdio.h>
long add_arrays_asm(long *arr1, long *arr2, unsigned long num, long *result);
int main()
{
printf("Testing add_arrays_asm\n");
long l3[] = {3, 23, 32, 121, 0, 43, 95, 4};
long l4[] = {-823,12,-1222,84834, -328, 0, 9, -1387};
long res1[] = {0, 0, 0, 0, 0, 0, 0, 0};
long sum1 = add_arrays_asm(l3, l4, 8, res1);
int j = 0;
for(j = 0; j < 8; j++) {
printf("%8ld + %8ld = %8ld\n", l3[j], l4[j], res1[j]);
}
printf(" Sum = %ld\n\n", sum1);
}
执行
ammarfaizi2@integral:/tmp/testz$ gcc -Wall -Wextra func.S main.c -o main
ammarfaizi2@integral:/tmp/testz$ valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./main
==748530== Memcheck, a memory error detector
==748530== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==748530== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==748530== Command: ./main
==748530==
Testing add_arrays_asm
3 + -823 = -820
23 + 12 = 35
32 + -1222 = -1190
121 + 84834 = 84955
0 + -328 = -328
43 + 0 = 43
95 + 9 = 104
4 + -1387 = -1383
Sum = 81416
==748530==
==748530== HEAP SUMMARY:
==748530== in use at exit: 0 bytes in 0 blocks
==748530== total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
==748530==
==748530== All heap blocks were freed -- no leaks are possible
==748530==
==748530== For lists of detected and suppressed errors, rerun with: -s
==748530== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
ammarfaizi2@integral:/tmp/testz$