2017-01-06 14 views
0

Является частью кода, к которому мы обращаемся с вызовом jmp, по-прежнему считается частью основной функции в сборке?Выскакивает из глобальной сети все еще рассматривается как часть основной функции, в сборке?

Пример:

main: 
    mov ebx,3 
    push ebx 
    jmp for_loop ; this part 
rec: 
    ;some function 
for_loop: 
    ;logic 
    je exit 
    call rec 
    ;logic 
    jmp for_loop 
exit: 
    pop ebx 
    mov eax,0 
    ret 

Было бы лучше практика, чтобы не использовать JMP и писать for_loop под main?

ответ

1

Ну, это похоже на беспорядок.

В сборке нет основной функции. Вы можете назвать точку входа, где начинается выполнение, «главное», но это действительно так. Это всего лишь мнимые метки, не существующие в машинных кодах. Функция была бы любой, что вы call, потому что инструкция процессора call выполняет некоторую настройку, когда он jmp s, но это все.

Лично я бы реструктурировал это совсем немного.

main: 
    xor ebx,ebx 
    add ebx,3   ; saves a byte 
    push ebx 
forloop: 
    ; I assume here you do a dec, or cmp, for the following: 
    je exit 
    ; put the code for "rec" in here. 
    ; No point wasting the bytes and time to jump. 
    jmp forloop 
exit: 
    pop ebx 
    xor eax,eax 
    ret 

Хорошо, так что это еще своего рода беспорядок, но есть дыры в моем знании о том, что вы пытаетесь достичь.

je exit в начале, вероятно, соединяется с «логикой», которая должна пройти до этого. Я бы скорее попытался раскрутить это, развернув его. Это означает, что если «логика» позволяет мне это сделать, я бы превратил ее в jne forloop и поставил ее в конец цикла, поэтому я могу избежать этого jmp до начала. Кроме того, вы снова сохраняете несколько байтов.

xor eax,eax - это более короткий и быстрый способ установки регистра на ноль. Если вы действительно нуждаетесь вrec, чтобы быть отдельной функцией, то, по крайней мере, поставить ее вне этого блока, чтобы вам не пришлось перепрыгивать через нее, используя jmp for_loop. Вы можете смело положить его после ret.

+0

Изменил 'jne exit'to' jne forloop', потому что иначе он не сработает. –

+0

Как вы думаете, что 'xor' +' add' "сохраняет байты"? Это 2 + 3 байта, тогда как 'mov ebx, 3' * также * 5 байтов. Одна и та же. Предпочитают одну инструкцию. –

+0

errr, вы правы, конечно. Я застрял на «xor» короче, игнорируя, что «add» уравнивает его. –

1

Вся часть:

rec: 
    ; some function (ending with ret?!) 

могут быть перемещены после ret, который находится в exit: части кода, то у вас будет «главный» вместе, и «ЗАП» по отдельности, как это:

main: 
    ; some init 
    ; some loop doing "call rec" 
    ; something something 
    ret 

rec: 
    ; some "function" code 
    ret 

опять же, это не имеет значения для CPU вообще, это не известно, каким-либо образом, что ваша логическая группировка команд в источнике или он находится внутри некоторой «функции» и «как глубоко» ,

ЦП имеет cs:eip адресный указатель, откуда он будет извлекать + выполнять следующую команду. Это все, что он знает в определенный момент исполнения.

Инструкция jmp загружает eip с другим адресом, тогда инструкция там будет выполнена.

Механизм «подпрограмм» работает путем хранения обратных адресов в стеке памяти, которые затем загружаются обратно в eip командой ret, но если вы отрегулируете содержимое стека другими способами, чтобы содержать недопустимый адрес возврата или другой, ret сбой или «переход» к другому адресу, ЦП не имеет понятия, что он «внутри» какой-то подпрограммы, и нет необходимости «возвращаться» из него. Все это высокоуровневая семантическая логика, написанная программистом, который отвечает за правильное проектирование путей выполнения, чтобы сформировать такие логические шаблоны, как «вызовы подпрограмм» или «основные петли».

ЦП имеет только cs:eip и содержимое других регистров и содержимое памяти, ничего больше. Независимо от того, что это состояние опережает выполнение команды, оно детерминистически налагает, какая инструкция будет выполняться следующей и какой эффект она будет иметь, - на содержимое регистров процессора и памяти компьютера (и других связанных фишек, либо по шине ввода/вывода, либо с помощью определенных части памяти как «управляемый» механизм управления вводом/выводом).


Так положить его другим способом вокруг, напишите ваш источник для легкого «чтения» человеком, не колеблясь, вкладывать больше времени в письменной форме легче/компактнее источник, как вы READ источник во много раз больше (отладка, изменение), чем WRITING it. Таким образом, в вашем примере имеет смысл переместить «rec» часть кода, чтобы не чередовать цепочку main-loop-ret «основного кода». Он должен лучше читать на исходном уровне.

Является частью кода, к которому мы обращаемся с вызовом jmp, все еще считается частью основной функции в сборке?

Зависит от читателя источника, считает ли он его частью основного или нет. Машина не заботится и не понимает такую ​​концепцию группировки команд.

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

  • Нет связанных вопросов^_^