大型機彙編(mainframe assembler/HLASM)之LOCTR

LOCTR--Multiple location counters

其主要作用就是爲了方便程序員編寫代碼,程序員可以把一個功能強大的程序分割成好多小的代碼段,然後在分別放在不同的PS/PDS dataset裏,而在每個dataset裏可以專門定製特定的變量爲本dataset裏的過程服務。

 000000                00000 00BE4  1530 DFHEISTG DSECT      
 ...             
 0003E9 4040404040404040            1650=LOGETEXT DC    CL120' ' 

                        
 000000                00000 02529  2677+ABC CSECT        
 ...
 0000EE D21F 51B8 B3C6 001B8 02020  2861          MVC   WKSTART,=CL32'WORKING'

                  
 001C5A                01C5A 02529  2922+ABC_CONSTANTS LOCTR  
 ...         
 001CB0 00000000                    2949+VARE             DC  XL4'00'  
              
 000461                00000 00BE4  2992+DFHEISTG DSECT  
 000461                00544 00544  2993+         ORG       
 ...        
 000550                             2998+TASK#Q           DS C 

            
 0004E0                00000 02529  3613+ABC LOCTR            
 ...
 001C58 07FF                        6558+          BR    R15 
  

 001D04                01C5A 02529  6565+ABC_CONSTANTS LOCTR                      
 001D04 D200 401C 2000 0001C 00000  6566 MVC2     MVC   DASIDATA(0),0(R2)   
 ...                                              
 002527 0E00                        6785                =X'0E00' 
                 
 000551                00000 00BE4  6790+DFHEISTG DSECT          
 000BE4                00BE4 00BE4  6791+         ORG  
 000BE4                             6792+DFHEIEND DS    0X    
                                    6793          END    

上面被編譯過後的程序代碼(這也是我們編寫程序代碼時的原始順序),請特別留意最左邊的地址的排序,下面來解析LOCTR的作用:

1. 首先,DFHEISTG是不適用於LOCTR的,我們可以把它看成是系統定義的一個宏,我們每次定義動態變量的時候,只要在我們想要加個的地方添加上類似紅色的代碼即可。但值得注意的是,一般都在開始處寫上ORG指令,其作用也很明顯,因爲我們要防着前面一個DFHEISTG裏定義變量的時候用了ORG來重定義,如果我們不在開始處寫ORG,就有可能我們新加的變量根本就沒開闢新的空間,而是接着對前面變量的重定義,很明顯這不是我們想要的。

2. 可以在同一個CSECT裏可以用LOCTR來設置多個counter,也可以說編譯器會設置多個基址寄存器,如上例,如果系統給ABC_CONSTANTS設置的基址寄存器爲R11,那麼變量VAR1的offset就應該是001CB0-001C5A=56,此時VAR1的地址就可以用B056來標識。

3. 這裏爲什麼ABC_CONSTANTS的開始地址爲001C5A而不是0?這是因爲前面001C5A(001C58+2,BR指令佔兩個字節)個字節的空間大小被ABC佔用了,其實,當本段代碼被彙編成objective code後,被真正執行的時候它們在內存的前後順序是

 000000                00000 02529  2677+ABC CSECT              
 ...
 0000EE D21F 51B8 B3C6 001B8 02020  2861          MVC   WKSTART,=CL32'WORKING'

 0000F4                00000 02529  3613+ABC LOCTR   
 ...
 001C58 07FF                        6558+          BR    R15  
                 
 001C5A                01C5A 02529  2922+ABC_CONSTANTS LOCTR 
 ...         
 001CB0 00000000                    2949+VAR1            DC  XL4'00'  

 001D04                01C5A 02529  6565+ABC_CONSTANTS LOCTR     
 ...                                              
 002527 0E00                        6785                =X'0E00' 
                 
 000000                00000 00BE4  1530 DFHEISTG DSECT  
 ...                                                    
 0003E9 4040404040404040            1650=LOGETEXT DC    CL120' ' 

 000461                00000 00BE4  2992+DFHEISTG DSECT          
 000461                00544 00544  2993+         ORG  
 ...     
 000550                             2998+TASK#Q           DS C

 000551                00000 00BE4  6790+DFHEISTG DSECT       
 000BE4                00BE4 00BE4  6791+         ORG 
 000BE4                             6792+DFHEIEND DS    0X    
                                    6793          END     

5. ABC_CONSTANTS開始處爲001C5A,此時系統會多加一個基址寄存器來存放當前地址,所以其偏移量爲0。

6. ABC_CONSTANTS的基址寄存器裏的數值應該比ABC的第一個基址寄存器(如果設置的話,而且設置的應該不止一個因爲1C5A>FFF,但是兩個足夠了因爲1C5A<2*FFF)裏的數值大001C5A

7.從代碼上可以看出ABC_CONSTANTS和ABC的結束地址都是02529,從此處也可以看出他們隸屬於同一個CSECT。


有疑問請聯繫QQ349106216


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章