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

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

Печать 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                                                        
               push bp              ;  Сохранить bp в стеке                     
               mov bp,sp            ;  Загрузить sp в bp                        
               mov ax,0             ;  Занести в ax 0                           
               mov cx,[bp+4]        ;  Переместить count в cx                   
               cmp cx,ax            ;  Cравнить cx c 0                          
               jle exit             ;  если 
     -----------------------------------------------------------------          
                                                                                
          Конечно,можно использовать другой путь: вызвать подпрограммы          
     Си  из модуля,  написанного на ассемблере.  Но при этом вы должны          
     сделать Си-функцию видимой из модуля,  написанного на ассемблере.          
     Мы уже вкратце обсудили,  как это делается:  функция  объявляется          
     как  EXTRN,  независимо от того,  какого она типа - near или far.          
     Например, вы написали следующую Си-функцию:                                
                                                                                
          long docalc(int *fact1, int fact2, int fact3);                        
                                                                                
          Для простоты предположим,  что docalc - это Си-функция (т.е.          
     противоположна Паскаль-функции).  Имея в виду использование  кро-          
     хотной,  малой или компактной модели памяти, вы должны Си-функцию          
     в модуле, написанном на ассемблере, объявить следующим образом:            
                                                                                
          EXTRN _docalc:near                                                    
                                                                                
          Подобно этому, если вы использовали среднюю, большую или ог-          
     ромную модели памяти, то объявите функцию как _docalc:far.                 
                                                                                
                                                                                
          docalc определяется тремя параметрами:                                
          - адресом ячейки памяти - xval;                                       
          - значением, хранимым в ячейке - imax;                                
          - константой 421 (десятичной).                                        
                                                                                
          Предположим  также,  что  вам  нужно  сохранить  результат в          
     32-разрядной ячейке памяти, называемой ans. Эквивалентный вызов в          
     Си будет таким:                                                            
                                                                                
          ans = docalc (xval, imax, 421);                                       
                                                                                
          Вам необходимо занести в стек сначала 421, затем imax, после          
     этого адрес xval и,  наконец,  вызвать docalc. При возврате нужно          
     очистить стек, который увеличился на 6 дополнительных байт, и за-          
     тем занести ответ в ячейки памяти ans и ans+2.                             
                                                                                
          Программа будет иметь вид:                                            
                                                                                
          mov ax,421        ;  Занести в стек 421                               
     push ax                                                                    
     push imax              ;  Занести в стек imax                              
     lea ax,xval            ;  Занести в стек xval                              

                         - 407,408 -
                                                                                
     push ax                                                                    
     call _docalc           ;  Вызов функции docalc                             
     add sp,6               ;  Очистка стека                                    
     mov ans,ax             ;  Занести 32-разрядный результат в ans             
     mov ans+2,dx           ;  Включая старшее слово                            
                                                                                
          А что  если  docalc будет использовать Паскаль-соглашение по          
     передаче параметров? Тогда вам придется изменить порядок парамет-          
     ров на обратный,  и не надо будет беспокоиться о чистке стека при          
     возврате,  т.к. это должна сделать вызываемая подпрограмма. Кроме          
     того, вы должны соблюдать Паскаль-соглашение при написании docalc          
     (без символа подчеркивания (_) и в верхнем регистре).                      
                                                                                
          Оператор EXTRN будет таким:                                           
                                                                                
          EXTERN DOCALC:near                                                    
                                                                                
     а программа вызова docalc будет иметь вид:                                 
                                                                                
          lea ax,xval      ;  Занести в стек xval                               
          push ax                                                               
          push imax        ;  Занести в стек imax                               
                                                                                
                                                                                
          mov ax,421       ;  Занести в стек 421                                
          push ax                                                               
          call DOCALC      ;  Вызов функции docalc                              
          mov ans,ax       ;  Занести 32-разрядный результат в ans              
          mov ans+2,dx     ;  Включая старшее слово                             
                                                                                
          Вот и все, что вам необходимо знать, чтобы вы могли  устано-          
     вить связь между языками.                                                  
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                

                         - 409,410 -
                                                                                
                  ПРОГРАММИРОВАНИЕ НА НИЗКОМ УРОВНЕ:                            
                псевдопеременные, встроенный ассемблер                          
                         и функции прерывания                                   
     -----------------------------------------------------------------          
                                                                                
          Предположим, что вы хотите выполнить  какие-то  действия  на          
     уровне  управления  машиной, но предпочитаете не испытывать труд-          
     ностей, связанных с созданием отдельного модуля на языке  ассемб-