написание простой функции в сборке x86-64 - PullRequest
0 голосов
/ 25 ноября 2018

Я пытаюсь написать первую функцию для лаборатории, написанную на языке ассемблера x86-64, которая называется multInts.Он умножит первый элемент intArray1 на первый элемент intArray2, а затем второй и т. Д. Прототип функции - void multInts(int size, int *array1, int *array2); Вот раздел .data для лаборатории:

.data
sizeIntArrays:
    .long 5
sizeShortArrays:
    .word 4
intArray1:
    .long 10
    .long 25
    .long 33
    .long 48
    .long 52
intArray2:
    .long 20
    .long -37
    .long 42
    .long -61
    .long -10

Вот чтоДо сих пор я писал:

##### MAIN FUNCTION
.text
.globl main
.type main,@function

main:
pushq %rbp
movq %rsp, %rbp

#pass parameters and call other functions
movl sizeIntArrays, %edi    #move size to registers for 1st parameter
leaq intArray1, %rsi        #load effective address of intArray1 to register rsi
leaq intArray2, %rdx        #load effective address of intArray2 to register rdx
movq $intArray1, %r10
movq $intArray2, %r11
call multInts           #call multInts function


movq $0, %rax           #return 0 to caller

movq %rbp, %rsp
popq %rbp
ret
.size main,.-main


##### MULTINTS
.globl multInts
.type multInts,@function

multInts:
pushq %rbp
movq %rsp, %rbp

#add code here for what the functions should do
movq $0, %r8            #initialize index for array access in caller save reg
movq $0, %rcx           #initialize 8 byte caller save result reg

loop0:
cmpl %r8d, %edi         #compare index to size
je exit0            #exit if equal
imulq (%r10, %r11), %rcx    #multiply elements of both array and store in result  reg
incq %r8            #increment index
jmp loop0

exit0:
movq $.LC0, %rdi
movq %rcx, %rsi
movq $0, %rax

call printf

movq %rbp, %rsp
popq %rbp
ret
.size multInts,.-multInts

Итак, мне сложно понять, как сделать указатель на intArray1 в соответствии с требованиями прототипа функции, а затем как правильно вызвать его в multIntsфункционировать?Я пытался использовать leaq для хранения адресов intArray1 & 2 в регистрах, но потом я не знаю, как получить доступ к значениям.Кроме того, я не совсем уверен, что правильно использую функцию imulq, чтобы умножить два значения вместе.Я продолжаю получать ошибку сегментации, как только код пытается выполнить multInts.Дайте мне знать, если потребуется дополнительная информация, и спасибо.

1 Ответ

0 голосов
/ 26 ноября 2018

.long совпадает с .int, а его размер составляет 4 байта.Следовательно, вы не можете обработать его напрямую с помощью imulq (за исключением того, что синтаксис неверен).Вы можете загрузить подписанное значение в x64-регистр с помощью movsx (синтаксис Intel) или movslq (синтаксис AT & T).

Полагаю, что RCX должен содержать сумму умножений.

Изменить

imulq (%r10, %r11), %rcx    #multiply elements of both array and store in result  reg

на

movslq (%rsi,%r8,4),%rax    # Load a long into RAX
movslq (%rdx,%r8,4),%r11    # Load a long into R11
imulq %r11, %rax            # RAX *= R11
addq %rax, %rcx             # RCX += RAX

и удалить

movq $intArray1, %r10
movq $intArray2, %r11

Вы не 'это не нужно.

...