История изменений
Исправление SZT, (текущая версия) :
Если разбирать сам код, там хватает неоптимальных моментов. Вот взять например https://github.com/codemeow/freelancer/blob/master/freelancer.asm#L154
.p_loop:
xor edx, edx
mov ebx, 10
idiv ebx
add edx, 30h
push rdx
inc ecx
cmp eax, 0
jnz .p_loop
.p_print:
pop rax
mov [v_loop_i], eax
p_s v_loop_i, 1
loop .p_print
Тут делается перевод в десятичную систему счисления, точнее в ascii цифры и выводится потом через вызов макроса p_s который вызывает p_str... Ну во-первых тут xor edx, edx
на каждой итерации цикла смысла делать нет, у тебя инструкция idiv в любом случае там переписывает. Во-вторых, инструкцию idiv (которой ты получаешь остаток от деления на 10 чтоб выцепить десятичный разряд) для оптимизации можно заменить инструкцией умножения, как это обычно делают компиляторы. Т.е. если GCC с флагом -O3 попросить это собрать: https://godbolt.org/z/j862j_
unsigned test(unsigned a)
{
return a%10;
}
test:
mov eax, edi
mov edx, 3435973837
imul rax, rdx
shr rax, 35
lea edx, [rax+rax*4]
mov eax, edi
add edx, edx
sub eax, edx
ret
Еще у тебя зачем-то на каждую выводимую цифру по одному вызову sys_write идет, это неоптимально, лучше одним большим вызовом все вывести чтоб не дергать ядро на каждый чих. А еще у тебя там цикл построен через инструкцию loop что тоже неоптимально, современные процессоры ее медленно исполняют https://stackoverflow.com/questions/35742570/why-is-the-loop-instruction-slow...
Ну и вот эти вот места
push rax
push rbx
push rcx
push rdx
...
pop rdi
pop rbx
pop rcx
pop rdx
mov ecx, 0
встречается, хотя xor ecx, ecx
инструкция короче, в общем тут много до чего можно докопаться, и перечислять слишком долго. Компилятор сделает лучше.Исходная версия SZT, :
Если разбирать сам код, там хватает неоптимальных моментов. Вот взять например https://github.com/codemeow/freelancer/blob/master/freelancer.asm#L154
.p_loop:
xor edx, edx
mov ebx, 10
idiv ebx
add edx, 30h
push rdx
inc ecx
cmp eax, 0
jnz .p_loop
.p_print:
pop rax
mov [v_loop_i], eax
p_s v_loop_i, 1
loop .p_print
Тут делается перевод в десятичную систему счисления, точнее в ascii цифры и выводится потом через вызов макроса p_s который вызывает p_str... Ну во-первых тут xor edx, edx
на каждой итерации цикла смысла делать нет, у тебя инструкция idiv в любом случае там переписывает. Во-вторых, инструкцию idiv (которой ты получаешь остаток от деления на 10 чтоб выцепить десятичный разряд) для оптимизации можно заменить инструкцией умножения, как это обычно делают компиляторы. Т.е. если GCC с флагом -O3 попросить это собрать: https://godbolt.org/z/j862j_
unsigned test(unsigned a)
{
return a%10;
}
test:
mov eax, edi
mov edx, 3435973837
imul rax, rdx
shr rax, 35
lea edx, [rax+rax*4]
mov eax, edi
add edx, edx
sub eax, edx
ret
Еще у тебя зачем-то на каждую выводимую цифру по одному вызову sys_write идет, это неоптимально, лучше одним большим вызовом все вывести чтоб не дергать ядро на каждый чих. А еще у тебя там цикл построен через инструкцию loop что тоже неоптимально, современные процессоры ее медленно исполняют https://stackoverflow.com/questions/35742570/why-is-the-loop-instruction-slow...
Ну и вот эти вот места
push rax
push rbx
push rcx
push rdx
...
pop rdi
pop rbx
pop rcx
pop rdx
mov ecx, 0
встречается, хотя xor ecx, ecx
инструкция короче, в общем тут много до чего можно докопаться, и перечислять слишком долго. Компилятор сделает лучше.