Турбо С: руководство пользователя. Часть 2

Турбо С: руководство пользователя. Часть 2 - Стр. 48

Печать PDF
Индекс материала
Турбо С: руководство пользователя. Часть 2
Стр. 2
Стр. 3
Стр. 4
Стр. 5
Стр. 6
Стр. 7
Стр. 8
Стр. 9
Стр. 10
Стр. 11
Стр. 12
Стр. 13
Стр. 14
Стр. 15
Стр. 16
Стр. 17
Стр. 18
Стр. 19
Стр. 20
Стр. 21
Стр. 22
Стр. 23
Стр. 24
Стр. 25
Стр. 26
Стр. 27
Стр. 28
Стр. 29
Стр. 30
Стр. 31
Стр. 32
Стр. 33
Стр. 34
Стр. 35
Стр. 36
Стр. 37
Стр. 38
Стр. 39
Стр. 40
Стр. 41
Стр. 42
Стр. 43
Стр. 44
Стр. 45
Стр. 46
Стр. 47
Стр. 48
Стр. 49
Стр. 50
Стр. 51
Стр. 52
Стр. 53
Стр. 54
Стр. 55
Стр. 56
Все страницы
                 PUBLIC  _min                                                   
          _min   PROC    near                                                   
                  .                                                             
                  .                                                             
                  .                                                             

                         - 393,394 -
                                                                                
                                                                                
          _min   ENDP                                                           
                                                                                
          Это верно в предположении,  конечно,  что функция min  будет          
     near-функцией. Если это far-функция, то вы должны заменить far на          
     near.  Заметим,  что min снабжено знаком подчеркивания для  того,          
     чтобы компоновщик Турбо Си мог корректно установить связи.                 
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                         Передача параметров                                    
     -----------------------------------------------------------------          
                                                                                
          Ваша первая задача -  выбрать  используемое  в  подпрограмме          
     соглашение по передаче параметров; учитывая приведенные ранее со-          
     ображения о трудностях  использования  Паскаль-соглашения,  будем          
     избегать  его  и использовать Си-метод.  Это означает,  что когда          
     вызвана функция min, стек выглядит следующим образом:                      
                                                                                
          SP + 04: v2                                                           
          SP + 02: v1                                                           
          SP:      адрес возврата                                               
                                                                                
          Если вы хотите получить  параметры,  не  изменяя  содержания          
     стека,  то для зтого необходимо сохранить базовый указатель (BP),          
     затем занести стековый указатель (SP) в  базовый  и  использовать          
     его в качестве указателя на стек для извлечения из него необходи-          
     мых вам величин.  Заметим,  что после занесения BP в стек относи-          
     тельные смещения параметров возрастут на 2, т.к. в стек будут до-          
     бавлены 2 байта.                                                           
                                                                                
                                                                                

                         - 395,396 -
                                                                                
                                                                                
                  Управление возвращаемыми величинами                           
     ----------------------------------------------------------------           
                                                                                
          Ваша функция возвращает целую величину;  куда вы ее помести-          
     те?  Для 16-битных (2-байтных) величин (char,  shot,  int,  enum,          
     near-указатели) вы используете регистр AX; для 32-битных (4-байт-          
     ных),  включающих far- и huge-указатели - регистр DX для старшего          
     слова  (или  для  адреса  сегмента у указателей) и регистр AX для          
     младшего слова.                                                            
                                                                                
          Величины float, double и long double возвращаются в регистре          
     top-of-stack (TOS) процессора 8087/80287, ST(0); если использует-          
     ся эмулятор 8087/80287, то величина возвращается  в  TOS  регистр          
     эмулятора.                                                                 
                                                                                
          Величины структур  возвращаются  путем занесения их в стати-          
     ческую ячейку памяти и передачей указателя на эту  ячейку  (в  АХ          
     для моделей с малыми данными, в DX:АХ для моделей с большими дан-          
     ными).                                                                     
                                                                                
          Вызывающая функция должна затем скопировать эту  величину  в          
                                                                                
     любом  месте,  где она необходима. Структуры длиной в 1 и 2 байта          
     возвращаются в АХ (подобно  любой  обычной  целой),  а  4-байтные          
     структуры в АХ и DX.                                                       
                                                                                
          В примере с min вы имеете дело с 16-битной величиной, поэто-          
     му можете поместить ответ в АХ.                                            
                                                                                
          Ваша программа выглядит теперь так:                                   
                                                                                
               PUBLIC _min                                                      
          _min PROC near                                                        
               push bp                    ;  Сохранить bp в стеке               
               mov bp,sp                  ;  Загрузить sp в bp                  
               mov ax,[bp+4]              ;  Переместить v1 в ax                
               cmp ax,[bp+6]              ;  Cравнить v1 и v2                   
               jle exit                   ;  если v1 > v2                       
               mov ax,[bp+6]              ;  Загрузить в ax v2                  
          exit: pop bp                    ;  Восстановить bp                    
 v2                      
                mov      ax,[bp+4]         ;  Загрузить в ax v2                 
          exit: pop      bp                ;  Восстановить bp                   
                ret      4                 ;  Очистка стека и возврат           
          MIN   ENDP                                                            
                                                                                
          И последний пример, демонстрирующий, почему вам может потре-          
     боваться использовать Си-соглашение по передаче параметров. Пред-          
     положим, вы переопределили min следующим образом:                          
                                                                                
                                                                                
          int  extern  min (int count, int v1, int v2, ...);                    
                                                                                
          Теперь min может получать любое количество целых чисел и бу-          
     дет возвращать минимальное из них. Однако, т.к. min не имеет воз-          
     можности автоматически узнавать, сколько значений ей передано, то          
     первым ее параметром будет величина count,  указывающая,  сколько          
     величин следуют за ней.                                                    
                                                                                
          Например, вы можете записать это так:                                 
                                                                                
          i = min (5, j, limit, indx, lcount, 0);                               
                                                                                
     предполагая,  что i, j, limit, indx и lcount - целые (или совмес-          
     тимого с int типа). Стек при входе будет выглядеть так:                    
                                                                                
          SP + 08:    (и т.д.)                                                  
          SP + 06:    v2                                                        
          SP + 04:    v1                                                        
          SP + 02:    count (счетчик)                                           
          SP:         адрес возврата (смещение)                                 
                                                                                
          Теперь модифицированная версия min имеет вид:                         

                         - 401,402 -