2015-11-18 3 views
0

Мне была предоставлена ​​функция в сборке, которая в основном преобразует заглавные буквы в строчные буквы. Вот некоторые из сборки,понимание указателей и литье в сборке

Q1: 
    pushq %rbp 
    movq %rsp, %rbp 
    subq $24, %rsp 
    movq %rdi, -24(%rbp) 
    movl $0, -4(%rbp) 
    movl $0. -8%(%rbp) 
    jmp .L2 
L2: 
    movl -4(%rbp) %edx 
    movq -24(%rbp), %rax 
    addq %rdx, %rax 
    movzbl (%rax), %eax 
    testb %al, %al 
    jne .L4 
    ... 

Большая часть остальных повторяется, но L2 является то, что на самом деле смущает меня. Это моя логика до сих пор: Мы сохраняем param1 в -24 (% rbp). Мы создаем local1 и local2, устанавливаем их как в 0, а затем переходим к L2. Я перемещаю local1 в% edx, param1 в% rax. Теперь это то, что меня пугает, Мне сказали следующую строку: addq попал в local1 как указатель на param1. Я просто решил добавить local1 + param1 и сохранить их в% rax. Как это возможно?

Дальше, movzbl. По моему мнению, мы разыскиваем% rax, поэтому получаем нечто вроде eax = (int) rax.

Мне также сказали подумать об этом как о преобразовании символа в int. Какая из них истинна, откуда я знаю, что я типизирую? А что, если у% rax не было круглых скобок вокруг него? Это int, потому что это 4 байта, а% eax - 32-битный регистр. Заранее благодарю вас за вашу помощь. Я потерял здесь ...

ответ

2

local1 не является указателем, это индекс (счетчик). Этот код делает что-то вроде:

void toupper(char* text) 
{ 
    int i = 0; /* at rbp-4 */ 
    int j = 0; /* unused, at rbp-8 */ 
    int ch;  /* in eax */ 
    while((ch = *(text + i)) != 0) 
    { 
     ... 
    } 
} 

Обратите внимание, что в C арифметика указателей *(text + i), конечно, эквивалентном text[i].

Да, movzbl является преобразованием unsigned char в int вы можете увидеть, что из самого названия команд: MOV е Z эро расширенного B YTE в L Онга.

Скобки обозначают разыменование указателя.

Смежные вопросы