Как работает арифметика leaq и memory в моей программе? - PullRequest
0 голосов
/ 20 сентября 2019

main.c

#include <stdio.h>

int mystery(char *, int);

char *str = "Reference letter";

int main () {
    int n = 16;

    printf("The return value was:  %d.\n", mystery(str,n));
    printf("%p\n", (&str));
    return 0;
}

mystery.s

.globl _mystery
_mystery:
    movl    $0, %eax
    leaq    (%rdi, %rsi), %rcx     

loop:
    cmpq    %rdi, %rcx
    jle     endl
    decq    %rcx
    cmpb    $0x65, (%rcx)
    jne     loop
    incl    %eax
    jmp     loop

endl:
    ret

•% rdi - первый аргумент, то есть char * str;

•% esiявляется вторым аргументом, т. е. int n;

•% eax - возвращаемое значение, int.

Я совершенно не понимаю, как работает этот оператор leaq (%rdi, %rsi), %rcx.Я знаю, что он выполняет некоторую адресную арифметику, и результат будет присвоен %rcx.%rdi является начальным адресом char *, который должен указывать на символ "R",% rsi должно быть 16. Допустим,% rdi равно 0x100,% rcx должно быть 0x10F.

Главной целью тайны должен быть подсчет числа «е» в строке «Ссылочная буква» в некоторой позиции.Он начинается с (% rdi,% rsi), затем начинается обратный отсчет.

Я тестировал программу в MacOS с использованием XCode.Когда n = 16, mystery возвращает 6. n = 14, возвращает 5, n = 5, 2.

Что меня смущает, так это то, что я ожидаю, что начальное значение% rcx будет 0x10F (при условии, что% rdi составляет 0x100).Поскольку каждому символу в C требуется 1 байт, адрес памяти также смещается на 1 байт.Так что% rcx должен указывать на 3-й символ в «Ссылочной букве», который должен быть «f».Но результат не кажется таким.Похоже, что это указывает на 16-й символ в строке.Поэтому я не совсем понимаю, как работает эта арифметика с памятью и leaq.В leaq (% rdi,% rsi),% rcx, (% rdi,% rsi) добавьте 16 к адресу% rdi, верно?Означает ли это, что он смещен на 16 байт или как?

...