Различие между ПЕРЕХОДОМ и ВЫЗОВОМ

Domain уже представлена ​​как крайняя левая таблица в объединении: FROM domains JOIN ..., поскольку она является первой таблицей, выбранной вами в списке выбора вашего запроса. Явное несвязанное соединение не является необходимым и приводит к вашей ошибке. Просто опустите его:

query = session.query(Domain.domain_name, Subdomain.subdomain_name, Title.title, Title.status, Title.response_len, Title.created_on, Title.updated_on)
query = query.join(Title).join(Subdomain)
23
задан Andronicus 1 February 2019 в 18:31
поделиться

3 ответа

Вы главным образом правы, если Вы говорите о CALL/JMP в x86 блоке или чем-то подобном. Основное различие:

  • JMP выполняет переход к местоположению, не делая ничего больше
  • , ВЫЗОВ продвигает указатель текущей команды на стеке (скорее: один после текущей команды), и затем JMPs к местоположению. С RET можно возвратиться туда, где Вы были.

Обычно, ВЫЗОВ является просто реализованным использованием функции удобства JMP. Вы могли сделать что-то как

          movl $afterJmp, -(%esp)
          jmp location
afterJmp:

вместо ВЫЗОВА.

25
ответ дан Anteru 29 November 2019 в 02:51
поделиться

Вы точно правы относительно различия между переходом и вызовом.

В демонстрационном случае единственной функции с хвостовой рекурсией, затем компилятор может снова использовать существующий стековый фрейм. Однако это может стать более сложным со взаимно рекурсивными функциями:

void ping() { printf("ping\n"); pong(); }
void pong() { printf("pong\n"); ping(); }

Рассматривают случай, где ping () и вонь () является более комплексными функциями, которые берут различные числа параметров. статья Mark Probst переговоры о реализации хвостовой рекурсии для GCC в мельчайших подробностях.

1
ответ дан Greg Hewgill 29 November 2019 в 02:51
поделиться

Я думаю, что Вы в общих чертах поняли.

Это зависит от архитектуры, но в целом, на аппаратном уровне:

  • команда перехода А изменится счетчик команд для продолжения выполнения в другой части программы.

  • команда вызова А продвинет текущее местоположение программы (или текущее местоположение + 1) к стек вызовов и перейдет к другой части программы. Инструкция по возврату затем вытолкает местоположение прочь стека вызовов и перейдет назад к исходному местоположению (или orignal местоположение + 1).

Так, команда перехода близко к GOTO, в то время как команда вызова близко к процедурному / вызову функции.

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

При изучении блока, я нахожу это легче при контакте с процессоры RISC, чем x86 процессоры, поскольку это имеет тенденцию иметь меньше инструкции и более простых операций.

0
ответ дан coobird 29 November 2019 в 02:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: