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