it-place.net > Уроци > Други
Не сте регистриран! Регистрирайте се БЕЗПЛАТНО, за да използвате услугите на сайта!

   Рубрики
 
 
 
 

 Форуми
» SEO и оптимизация
» Всичко за PHP и Perl
» Всичко за C, C++ и .NET
» Всичко за Java и JSP
» Всичко за SQL и MySQL
» Всичко за XHTML и CSS
» Презентация на сайтове
 Асемблер за по-напреднали: Малки трикове...
  1. Малки трикове-Аритметика
  2. Малки трикове-Функции Min/Max
  3. Използване на инструкцията LEA
  4. Цикли
  5. Проверка на сложни условия
     
Автор  johnfound (11.06.2004 17:31)  съобщение до автора
Погледнат  3446 пъти  добави към любими
Оценка  добави коментар
Гласове  1  изпрати на приятел
Коментари  (0)  абонирай се за Други
    Страница 2 / 5

 



1.2 Функции Min/Max

Задачата е: Имаме две беззнакови числа в два регистъра да кажем eax и ebx. На изхода, в eax трябва да е по-малкото/по-голямото от двете числа. Задачата да се реши без преходи.

Ето го и решението с използване на един допълнителен регистър:

CODE
1
2
3
4
5
6
7
8
9
10
11
;---------------------------------
; Вход:
;  
eax, ebx - 2 числа без знак
; Изход:
;  
eax = min(eax, ebx)
;---------------------------------
.
min:
       
sub     ebx,eax
        sbb     ecx
,ecx
       
and     ecx,ebx
        add     eax
,ecx

Как работи:

След първата инструкция, в ebx имаме разликата между двете числа (тоест това е числото, което трябва да прибавим към eax, за да получим числото в ebx)

Флагът CF = 1 ако ebx<eax или CF=0 ако ebx>eax.

Втората инструкция нулира ecx, ако CF=0 и запълва ecx с 1-ци (ecx=-1) ако CF=1 (напомням, че инструкцията sbb op1, op2 извършва следната операция: op1 = op1 - op1 - CF)

Третата инструкция вкарва в ecx стойността на разликата (ebx) но само ако ecx = (-1). Иначе ecx си остава 0 ( and със 0 = 0 )

И накрая последната инструкция или събира eax със 0 (ако ecx e 0, тоест ако ebx>eax на входа) или събира eax с разликата (ebx-eax) ако ecx = (ebx-eax), тоест ако на входа ebx < eax. Но eax+(ebx-eax) е точно равно на ebx -> тоест на изхода eax ще е равно на входното ebx.

За да приспособим този код за функцията max, трябва само да инвертираме (not) стойността на ecx след инструкцията sbb.
Тогава ще имаме ecx = -1 ако CF=0 (ebx>eax) и съответно ecx=0 ако CF=1 (ebx<eax).
Ето го и пълният код:
CODE
1
2
3
4
5
6
7
8
9
10
11
12
;---------------------------------
; Вход:
;  
eax, ebx - 2 числа без знак
; Изход:
;  
eax = max(eax, ebx)
;---------------------------------
.
max:
       
sub     ebx,eax
        sbb     ecx
,ecx
       
not     ecx
       
and     ecx,ebx
        add     eax
,ecx

Смятам, че работата на този код не се нуждае от пояснения.
Само ще добавя, че за постигане на максимална скорост, инструкциите трябва да се сдвоят правилно с други инструкции за паралелно изпълнение.

Оригинала на кода за функцията min е на Агнер Фог. Модификацията за изпълнение на max е на автора на тази статия.




 << Предишна страница Следваща страница >> 


Ключови думи: аритметика трик асемблер


Още уроци от тази рубрика


 
  • Подобни теми от myLinks
 

 За автора: johnfound  
Занимавам се с програмиране от 1983 година. Експерт по програмиране на Delphi и Assembler. Разбира се понякога работя и на PHP, Perl и др.под. В момента се занимавам с програмиране на автоматизирани системи за производство в голяма немска фирма в България. От 2003г започнах проект с отворен код, целта на който е разработката на съвременна среда и средства за програмиране на асемблер под Windows, конкурентна на езиците от високо ниво. Подробности за проекта можете да намерите на: http://fresh.flatassembler.net
   
 2 посетители четат този урок (0 потребители и 2 гости)  
Активни потребители: ---
   
  

Еmail  
 

 

 
  • Интересно от Софтуер
 



IT-PLACE.NET © 2004 - 2008