Baixe o app para aproveitar ainda mais
Prévia do material em texto
�PAGE �Erro! Indicador não definido.� PURYB - CONSULTORIA EM INFORMÁTICA LTDA. � �PAGE �218� ASSEMBLER - PROF. ALBERTO ROMANO SCHIESARI ASSEMBLER para Mainframes IBM Prof. Alberto Romano Schiesari (1a edição: 1974; última revisão:Julho/2009) � SUMÁRIO 71. Introdução � 71-1 A Linguagem Assembler � 71-2 Revisão dos Sistemas de Numeração Binário e Hexadecimal � 81-2-1 Conversões � 81-2-1-1 Conversão de decimal para binário � 101-2-1-2 Conversão de decimal para hexadecimal � 111-2-1-3 Conversão de binário para hexadecimal � 121-2-1-4 Conversão de hexadecimal para binário � 131-2-1-5 Conversão de binário para decimal � 141-2-1-6 Conversão de hexadecimal para decimal � 151-2-2 Operações aritméticas � 151-2-2-1 Soma em binário � 161-2-2-2 Subtração em binário � 171-2-2-3 Soma em hexadecimal � 181-2-2-4 Subtração em hexadecimal � 191-3. Arquitetura de Mainframes IBM � 191-3-1 Visão Geral � 221-3-2 Endereçamento � 22BASE + DESLOCAMENTO � 23INDEXADOR + BASE + DESLOCAMENTO � 24Deslocamento máximo; uso de bases � 26Carga de registradores base � 301-3-3 Representação de Dados � 301-3-3-1 Formato binário de ponto fixo � 311-3-3-2 Formato decimal zonado � 311-3-3-3 Formato decimal compactado � 311-3-3-4 Formato caractere (padrão EBCDIC) � 321-3-4 Representação de Instruções � 32RR - 2 bytes � 32E - 2 bytes � 32QST - 4 bytes � 32QV - 4 bytes � 32RRE - 4 bytes � 32RS - 4 bytes � 32RX - 4 bytes � 32S - 4 bytes � 32SI - 4 bytes � 33VR - 4 bytes � 33VS - 4 bytes � 33VST - 4 bytes � 33VV - 4 bytes � 33RSE - 6 bytes � 33SS - 6 bytes � 33SSE - 6 bytes � 382. Montador Assembler e Especificação de Elementos � 382-1. Introdução � 382-1-1 O Montador Assembler � 402-1-2 O Statement Assembler � 402-2. Símbolo � 412-3. Código de Instrução � 412-3-1 Instruções ao Montador � 412-3-2 Instruções de Máquina � 412-3-3 Macro-Instruções � 412-4. Operandos e Comentários � 412-4-1 Operandos em Registrador � 422-4-2 Operandos em Memória � 422-4-2-1 Termos de Expressões � 432-4-2-2 Expressões para referência de Operandos � 452-5. Continuação de Statements � 452-6. Identificação e Sequência de Statements � 463. Instruções ao Montador Assembler � 463-1. Instruções para definição de áreas � 46DC (Define Constant - Definir Constante) � 47TABELA DE CONSTANTES � 48DC tipo C � 48DC tipo X � 48DC tipo B � 49DC tipo F � 49DC tipo H � 49DC tipo P � 49DC tipo Z � 50DC tipo A � 51DC tipo Y � 51DC tipo S � 51DC tipo V � 51DC tipo Q � 52DS (Define Storage - Definir Memória) � 533-2. Literais � 543-3. Outras instruções ao montador � 54CCW ou CCW0 (Channel Command Word - Palavra de Comando de Canal) � 55CCW1 (Channel Command Word - Palavra de Comando de Canal) � 56START (Começo) � 56CSECT (Control Section - Seção de Controle) � 57DSECT (Dummy Section - Seção Simulada) � 57DXD (Define External Dummy Section - Definir Dummy Section Externa) � 58CXD � 58COM (Blank Common Control Section - Seção de Controle Branca Comum) � 59LOCTR (Multiple Location Counters - Múltiplos Contadores de localização) � 60AMODE (Adressing Mode - Modo de endereçamento) � 60RMODE (Residence Mode - Modo de residência) � 61ENTRY (Entrada) � 61EXTRN (External - Externo) � 61WXTRN � 62USING (Usando) � 62DROP (Por de lado, Deixar) � 63TITLE (Título) � 63EJECT (Ejetar) � 63SPACE (Espaço) � 64PRINT (Impressão) � 64ICTL (Input Control - Controle de Entrada) � 65ISEQ (Input Sequence - Sequência de Entrada) � 65PUNCH (Perfure) � 65REPRO (Reproduza) � 66ORG � 66EQU (Equate - Igualar) � 67OPSYN (Operation Code Synonim - Sinônimo para código de operação) � 67PUSH (Empurrar) � 67POP � 67LTORG � 68CNOP (Conditional Nop - Nop Condicional) � 68COPY (Copiar) � 68END (Fim) � 724. Instruções de Máquina � 744-1. Instruções de movimento de memória para memória � 74MVC (Move Character - Movimentar Caracteres) � 75MVZ (Move Zones – Movimentar Zonas) � 75MVN (Move Numerics - Movimentar Numéricos) � 76MVI (Move Immediate - Movimentar Imediato) � 77MVO (Move with Offset – Movimetar com deslocamento) � 78ZAP (Zero and Add Packed – Zerar e Somar em Compactado) � 79MVCL (Move Long – Mover [campo] Longo) � 80PACK (Compactar) � 81UNPK (Unpack – descompactar) � 82MVCIN (Move Inverse – Mover invertido) � 834-2. Instruções aritméticas com campos compactados � 83AP (Add Packed – Somar em compactado) � 84SP (Subtract Packed – Subtrair em compactado) � 85MP (Multiply Packed – Multiplicar em compactado) � 85DP (Divide Packed – Dividir em compactado) � 86SRP (Shift and Round Packed – Deslocar e arredondar compactado) � 874-3. Instruções de comparação � 87CP (Compare Packed – Comparar em compactado) � 87CLC (Compare Logical Character – Comparar Caracteres Logicamente) � 87CLI (Compare Logical Immediate - Comparar Logicamente com Operando Imediato) � 88CLCL (Compare Logocal Character Long – Comparar Logicamente campos longos) � 89C (Compare) � 89CH (Compare Halfword) � 90CL (Compare Logical – Compare Logicamente) � 90CLM (Compare Logical Characters Under Mask - Comparar campos lógicamente, sob máscara) � 91CR (Compare Register – Comparar Registradores) � 91CLR (Compare Logical Register – Comparar Registradores Logicamente) � 924-4. Instruções de desvio � 924-4-1 Introdução e mnemônicos � 944-4-2 Instruções de desvio condicional e incondicional � 94BC (Branch on Condition – Desviar na Condição) � 94BCR (Branch on Condition Register – Desviar [para endereço de registrador] na Condição) � 954-5. Instruções de controle de loop � 95BCT (Branch on Count – Desvie na condição [de contagem] testada) � 95BCTR (Branch on Count Register – Desvie na condição [de contagem] testada para [endereço contido em] registrador) � 96BXH (Branch on Index High – Desvie se o Índice for Maior) � 97BXLE (Branch on Index Low or Equal – Desvie se o Índice for Menor ou Igual) � 984-6. Instruções de edição � 98ED (Edit – Editar) � 99EDMK (Edit and Mark – Editar e Marcar) � 1004-7. Instruções de tradução e teste de bytes � 100TR (Translate – Traduzir) � 101TRT (Translate and Test – Traduzir e Testar) � 1024-8. Shift (deslocamento de bits) em registradores � 102SLL (Shift Left Logical – Deslocamento Simples Lógico à esquerda) � 102SRL (Shift Right Logical – Deslocamento Simples Lógico à direita) � 103SLDL (Shift Left Double Logical – Deslocamento Duplo Lógico à esquerda) � 103SRDL (Shift Right Double Logical – Deslocamento Duplo Lógico à direita) � 104SLA (Shift Left Algebraic – Deslocamento Simples Algébrico à esquerda) � 104SRA (Shift Right Algebraic – Deslocamento Simples Algébrico à direita) � 105SLDA (Shift Left Double Algebraic – Deslocamento Duplo Algébrico à esquerda) � 105SRDA (Shift Right Double Algebraic – Deslocamento Duplo Algébrico à direita) � 1064-9. Instruções de álgebra booleana � 106N (And – E) � 107O (Or – Ou) � 107X (Exclusive Or – Ou exclusivo) � 108NR (And Register – E entre registradores) � 108OR (Or Register – Ou entre registradores) � 108XR (Exclusive or Register – Ou exclusivo entre registradores) � 109NI (And Immediate – E [com operando] imediato) � 109OI (Or Immediate – Ou [com operando] imediato) � 109XI (Exclusive Or Immediate – Ou exclusivo [com operando] imediato) � 110NC (And Character – E entre campos com caracteres) � 110OC (Or Character – Ou entre campos com caracteres) � 110XC (Exclusive Or Character – Ou exclusivo entre campos com caracteres) � 1114-10. Instruções de carga e desvio � 111BALR (Branch and Link Register – Desviar e ligar via registrador) � 112BAL (Branch and Link – Desviar e ligar) � 113BAS (Branch and Save – Desviar e salvar) � 114BASR (Branch and Save Register – Desviar para endereço em registrador e salvar) � 115BASSM (Branch and Save and Set Mode – Desviar, salvar e posicionar modo) � 116BSM (Branch and Set Mode – Desviar e posicionar modo) � 1174-11. Instruções de movimento de dadosde registrador para memória � 117ST (Store – Armazenar) � 117STH (Store Halfword – Armazenar halfword) � 118STM (Store Multiple – Armazenar Múltiplos) � 118STC (Store Character – Armazenar um byte) � 119STCM (Store Characters under Mask – Armazenar caracteres por máscara) � 119CVD (Convert to decimal – Converter [de binário] para [decimal] compactado) � 1204-12. Instruções de movimento de dados de campo de memória para registrador � 120L (Load – Carregar) � 120LH (Load Halfword – Carregar halfword) � 121LM (Load Multiple – Carregar Múltiplos) � 121IC (Insert Character – Inserir Byte) � 122ICM (Insert Character under Mask – Inserir bytes sob máscara) � 122CVB (Convert to binary – Converter [de compactado] para binário) � 1234-13. Instruções de movimento de dados de registrador para registrador � 123LR (Load Register – Carregar registrador) � 123LPR (Load Positive Register – Carregar registrador positivo) � 124LNR (Load Negative Register – Carregar registrador negativo) � 124LCR (Load Complement Register – Carregar o complemento do registrador) � 125LTR (Load and test Register – Carregar e testar registrador) � 1264-14. Operações aritméticas entre registradores � 126AR (Add Register – Somar registradores) � 126SR (Subtract Register – Subtrair registradores) � 127MR (Multiply Register – Multiplicar registradores) � 127DR (Divide Register – Dividir registradores) � 128ALR (Add Logical Register – Somar registradores logicamente) � 128SLR (Subtract Logical Register – Subtrair registradores logicamente) � 1294-15. Operações aritméticas entre registradores e campos de memória � 129A (Add – Somar) � 129S (Subtract – Subtrair) � 130M (Multiply – Multiplicar) � 130D (Divide – Dividir) � 131AH (Add Halfword – Somar hafword) � 131SH (Subtract Halfword – Subtrair hafword) � 132MH (Multiply Halfword – Multiplicar hafword) � 132AL (Add Logical – Somar logicamente) � 133SL (Subtract Logical – Subtrair logicamente) � 1344-16. Outras instruções � 134LA (Load Address – Carregar Endereço) � 134TM (Test Under Mask – Testar com máscara) � 135EX (Execute) � 135SVC (Supervisor Call – Chamada ao Supervisor) � 136MC (Monitor Call – Chamada do monitor) � 136SPM (Set Program Mask – estabelecer máscara de programa) � 136IPM (Insert Program Mask – inserir máscara de programa) � 137STCK (Store clock – armazenar clock) � 137TS (Test and Set – Testar e posicionar) � 137CS (Compare and Swap – Comparar e Trocar) � 138CDS (Compare Double and Swap – Comparar double e Trocar) � 1395. Macro-Instruções � 1395-1. Introdução � 1405-2. Símbolos variáveis e de sequência � 1435-3. Expressões � 1445-4. Variáveis de montagem : declaração e atribuição de conteúdo � 1465-5. ANOP, MNOTE e AREAD � 146ANOP � 146MNOTE � 1485-6. MHELP � 1495-7. Desvios - AGO, ACTR E AIF � 1505-8. Parâmetros posicionais e keyword � 1525-9. Funcionamento das macros - exemplos � 1525-9-1 Macro sem símbolo e sem parâmetros � 1525-9-2 Macro com símbolo fixo e sem parâmetros � 1535-9-3 Macro com símbolo variável e sem parâmetros � 1535-9-4 Macro com símbolo variável e com 1 parâmetro posicional � 1545-9-5 Macro com símbolo variável e com 2 parâmetros posicionais � 1545-9-6 Macro com símbolo variável e com 1 parâmetro keyword (sem default) � 1555-9-7 Macro com símbolo variável e com 1 parâmetro keyword (com default) � 1555-9-8 Macro com símbolo variável e com 2 parâmetros keyword (sem default) � 1565-9-9 Macro com símbolo variável e com 2 parâmetros keyword (com default) � 157A P E N D I C E S � 158APÊNDICE A - Instruções (ordem alfabética de mnemônico e ordem código de instrução) � 169APÊNDICE B - Tabelas de potências de 2 e 16 � 171APÊNDICE C - Caracteres EBCDIC � 172APÊNDICE D - Caracteres ASCII � 173APÊNDICE E – Caracteres de controle de impressão � 174APÊNDICE F - Interrupções por erro de programa � 175APÊNDICE G - Truques úteis a programas Assembler � 177APÊNDICE H – Exemplos de macro instruções MVS � 178APÊNDICE I - Exemplo de programa MVS � 179APÊNDICE J – Exemplos de macro Instruções VSE � 180APÊNDICE K - Exemplo de programa VSE � 181APÊNDICE L – Exemplo de macro instruções VM � 182APÊNDICE M - Exemplo de programa VM � 183APÊNDICE N - Macro instruções XEGUEI e TCHAU � 187APÊNDICE O - Exemplo de Subrotina � 188APÊNDICE P - Exemplo 2 de subrotina � 190APÊNDICE Q - Montagem de programa de demonstração 1 � 203APÊNDICE R - Montagem de programa de demonstração 2 � 214EXERCíCIOS PROPOSTOS � 228EXERCÍCIOS RESOLVIDOS � � � 1. Introdução 1-1 A Linguagem Assembler Convém observar que, como toda linguagem Assembler, esta, para poder ser melhor compreendida e utilizada em seu pleno potencial, exige o conhecimento da arquitetura do equipamento no qual ela é utilizada. Uma revisão nos conceitos e princípios básicos da arquitetura IBM é fundamental para o acompanhamento deste curso, recomendando-se a leitura do Principles of Operation do equipamento. 1-2 Revisão dos Sistemas de Numeração Binário e Hexadecimal A base do sistema de numeração binário é 2. Ele possui 2 algarismos, cujos símbolos gráficos são o 0 e o 1. Cada algarismo tem seu valor dependendo da posição que ocupa no número. A base do sistema de numeração hexadecimal é 16. Ele possui 16 algarismos, cujos símbolos gráficos são: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E e F. Cada algarismo tem seu valor dependendo da posição que ocupa no número. TABELA BÁSICA DE EQUIVALÊNCIA DECIMAL HEXA BINÁRIO DECIMAL HEXA BINÁRIO 0 0 0000 8 8 1000 1 1 0001 9 9 1001 2 2 0010 10 A 1010 3 3 0011 11 B 1011 4 4 0100 12 C 1100 5 5 0101 13 D 1101 6 6 0110 14 E 1110 7 7 0111 15 F 1111 � 1-2-1 Conversões 1-2-1-1 Conversão de decimal para binário Dividir o número decimal desejado por 2 e "guardar" o resto (que só pode ser 0 ou 1); o cociente dessa divisão deve ser calculado somente em sua parte inteira, e deve-se dividi-lo por 2, "guardando" o resto, e assim por diante, até que o cociente seja zero. Em seguida, os restos devem ser anotados, do último para o primeiro, da esquerda para a direita; o número formado pelos restos transcritos dessa forma, será o número binário equivalente ao decimal que se desejava converter para binário. Exemplo: achar o número binário equivalente ao decimal 154. 154 / 2 = cociente 77 resto 0 77 / 2 = cociente 38 resto 1 38 / 2 = cociente 19 resto 0 19 / 2 = cociente 9 resto 1 9 / 2 = cociente 4 resto 1 4 / 2 = cociente 2 resto 0 2 / 2 = cociente 1 resto 0 1 / 2 = cociente 0 resto 1 Portanto, o número binário 10011010 vale 154 em decimal. Se o número for negativo: Converter o mesmo número decimal positivo para binário, conforme exposto acima Inverter os bits (bit 0 transformar em 1; bit 1 transformar em 0) Somar 1 (ver item 1.2.2.1 – Somar em binário) Preencher com 1’s à esquerda até completar a quantidade de bits do campo desejado (16 se halfword, 32 se full-word ou 32 se double-word) Exemplos: (154)10 = (10011010)2 10011010 invertido : 01100101 somando 1 : + 1 -------- 01100110 completando à esquerda com 1’s para completar 16 bits (halfword): 1111111101100110 Portanto: (-154)10 = (1111111101100110)2 = (FF66)16 (7)10 = (111)2 111 invertido : 000 somando 1 : + 1 -------- 001 completando à esquerda com 1’s para completar 16 bits (halfword): 1111111111111001 Portanto: (-7)10 = (1111111111111001)2 = (FFF9)16 EXERCÍCIOSPROPOSTOS Converter de decimal para binário: EP001: 987654 EP002: 4095 EP003: 7 EP004: 1023 EP005: 4096 EP006: 255 EP007: 1024 EP008: 10010001 EP009: 256 EP010: 1025 EP011: 999888 EP012: 65432 � 1-2-1-2 Conversão de decimal para hexadecimal Dividir o número decimal desejado por 16 e "guardar" o resto (que só pode ser de 0 a 15); o cociente dessa divisão deve ser calculado somente em sua parte inteira, e deve-se dividi-lo por 16, "guardando" o resto, e assim por diante, até que o cociente seja zero. Em seguida, os restos devem ser anotados, do último para o primeiro, da esquerda para a direita, observando-se que se o resto for 10 deve-se transcrever A, e assim por diante, de acordo com a tabela básica de equivalência colocada na introdução do tópico 1-2; o número formado pelos restos transcritos dessa forma, será o número hexadecimal equivalente ao decimal que se desejava converter para hexadecimal. Exemplo: determinar o número hexadecimal equivalente ao decimal 1234567. 1234567 / 16 = cociente 77160 resto 7 77160 / 16 = cociente 4822 resto 8 4822 / 16 = cociente 301 resto 6 301 / 16 = cociente 18 resto 13 13 / 16 = cociente 0 resto 13 Portanto, DD687 é o número hexadecimal equivalente ao decimal 1234567. EXERCÍCIOS PROPOSTOS Converter de decimal para hexadecimal: EP013: 987654 EP014: 4095 EP015: 7 EP016: 1023 EP017: 4096 EP018: 255 EP019: 1024 EP020: 10010001 EP021: 256 EP022: 1025 EP023: 999888 EP024: 65432 � 1-2-1-3 Conversão de binário para hexadecimal Basta separar o número binário em grupos de 4 algarismos, da direita para a esquerda (completando com zeros à esquerda, o último grupo à esquerda, se for necessário para completar 4 algarismos), e, em seguida, colocar, para cada grupo de 4 algarismos binários, o algarismo hexadecimal equivalente, conforme a tabela básica de equivalência colocada na introdução do tópico 1-2. Exemplo: determinar o número hexadecimal equivalente ao binário 11001101010001010000011. 0110 0110 1010 0010 1000 0011 6 6 A 2 8 3 Portanto, 66A283 é o número hexadecimal equivalente ao binário 11001101010001010000011. EXERCÍCIOS PROPOSTOS Converter de binário para hexadecimal: EP025: 11111000111010100100001 EP026: 1000000111000111111110000011111110 EP027: 1100 EP028: 11111110001 EP029: 1010101010101000110011000111 EP030: 110011001100110011001 EP031: 1000000000000001 EP032: 1000000001 EP033: 111111100000001111111 EP034: 1 EP035: 1100101011111110 EP036: 101011010111000111000000001111110001111 � 1-2-1-4 Conversão de hexadecimal para binário Basta transcrever, para cada algarismo hexadecimal, o grupo de 4 algarismos binários a ele correspondente, conforme a tabela do item anterior. Para o último grupo à esquerda pode-se deixar de transcrever os zeros binários à esquerda não significativos. Exemplo: determinar o número binário correspondente ao hexadecimal 1AB4C. 1 A B 4 C 0001 1010 1011 0100 1100 Portanto, o número binário 11010101101001100 é equivalente ao hexadecimal 1AB4C. EXERCÍCIOS PROPOSTOS Converter de hexadecimal para binário: EP037: CAFE EP038: CDF EP039: 1AB4D EP040: 15 EP041: F EP042: 87B54 EP043: 1001 EP044: 234 EP045: CAD EP046: 7F7 EP047: 1990 EP048: 33 � 1-2-1-5 Conversão de binário para decimal Deve-se efetuar a soma das potências de 2 correspondentes aos algarismos 1 do número binário. Exemplo: determinar o número decimal equivalente ao binário 111001101. 1 . (2**8) = 1 . 256 = 256 1 . (2**7) = 1 . 128 = 128 1 . (2**6) = 1 . 64 = 64 0 . (2**5) = 0 . 32 = 0 0 . (2**4) = 0 . 16 = 0 1 . (2**3) = 1 . 8 = 8 1 . (2**2) = 1 . 4 = 4 0 . (2**1) = 0 . 2 = 0 1 . (2**0) = 1 . 1 = 1 TOTAL 461 Portanto, o número decimal 461 é equivalente ao binário 111001101. EXERCÍCIOS PROPOSTOS Converter de binário para decimal: EP049: 11 EP050: 100001111111 EP051: 101010010101 EP052: 110000001111111 EP053: 11111110000011 EP054: 11110000111000 EP055: 11 EP056: 111111110 EP057: 1111100001111000111001101 EP058: 1000000000000 EP059: 11111001 EP060: 1000000000000001 � 1-2-1-6 Conversão de hexadecimal para decimal Deve-se efetuar a soma das potências de 16 multiplicadas pelo valor decimal do algarismo hexadecimal. Exemplo: determinar o número decimal equivalente ao hexadecimal 1AC5F. 1 . (16**4) = 1 . (16**4) = 1 . 65536 = 65536 A . (16**3) = 10 . (16**3) = 10 . 4096 = 40960 C . (16**2) = 12 . (16**2) = 12 . 256 = 3072 5 . (16**1) = 5 . (16**1) = 5 . 16 = 80 F . (16**0) = 15 . (16**0) = 15 . 1 = 15 TOTAL 109663 Portanto, o número decimal 109663 é equivalente ao hexadecimal 1AC5F. EXERCÍCIOS PROPOSTOS Converter de hexadecimal para decimal: EP061: 11 EP062: AAF45 EP063: 1B567 EP064: 100 EP065: 1000 EP066: FF EP067: FFF EP068: CDF EP069: CAFE EP070: FACA EP071: DAD0 EP072: F1E2D3C4 � 1-2-2 Operações aritméticas 1-2-2-1 Soma em binário Os números devem estar alinhados à direita. Análoga à soma em decimal, observando-se a seguinte "tabuada": 0 + 0 = 0 0 + 1 = 1 1 + 0 = 1 1 + 1 = 0 e vai 1 para a "casa" da esquerda Exemplos: 11001001 1001111011 111 + 1010 + 110110 + 1 ----------- ------------- ------ 11010011 1010110001 1000 EXERCÍCIOS PROPOSTOS EP073: 11001100 + 10101010 EP074: 1111001111 + 1001111001 EP075: 1111 + 1 EP076: 1111 + 111 EP077: 100001 + 11110 EP078: 1011110011 + 111101111 EP079: 110011001100 + 101011110000 EP080: 1111100001111000 + 101111 EP081: 111 + 1111 + 100 EP082: 11 + 111 + 1111 + 11111 EP083: 1111 + 1001 + 111 + 101 + 11 + 1 EP084: 111 + 1000 + 1 + 1100 � 1-2-2-2 Subtração em binário Os números devem estar alinhados à direita. A subtração é análoga à soma em decimal, observando-se a seguinte "tabuada": 0 - 0 = 0 1 - 0 = 1 1 + 1 = 0 0 - 1 = tira-se 1 da "casa" da esquerda (que fica valendo 1 a menos), e que vem para a "casa" presente valendo 2 Exemplos: 11001001 1001111011 100 100 - 1010 - 110110 - 1 - 1000 ----------- ------------- ------ --------- 10111111 1001000101 11 ...1111100 EXERCÍCIOS PROPOSTOS EP085: 11001100 - 1010101 EP086: 1111001111 - 1111001 EP087: 1111 - 1 EP088: 1111 - 111 EP089: 100001 - 11110 EP090: 1011110011 - 111101111 EP091: 11001100 - 111011110000 EP092: 1111000 + 101010111 EP093: 111 - 1111 EP094: 10001 - 111111 EP095: 0 - 1 EP096: 0 - 10 � 1-2-2-3 Soma em hexadecimal Os números devem estar alinhados à direita. Análoga à soma em decimal, observando-se que só vai 1 para a "casa" da esquerda quando o resultado da soma de dois algarismos das duas parcelas for maior que 15 (o algarismo resultante deve ser a soma achada - 16). Os resultados de cada "casa" devem ser colocados em algarismos hexadecimais (se for 10, coloca-se A; e assim por diante, até o 15, que coloca-se F). Exemplos: 1AB4 CF55 A2BC89 FFF F0F0 + 123 + 102D + F00F +4 + CCCC ------- ------- --------- ------- -------- 1BD7 DF82 A3AC98 1003 1BDBC EXERCÍCIOS PROPOSTOS EP097: F12B + 321 EP098: 1100 + 111 EP099: 1000F + F0001 EP100: A9B8C7 + D6E5F4 EP101: CAFE + CDF EP102: B001 + FD EP103: 999 + 111 EP104: 123456 + 789ABC EP105: FFF + EEE EP106: DDD + 333 EP107: 987AED + CF01 EP108: FACA + CAFE � 1-2-2-4 Subtração em hexadecimal Os números devem estar alinhados à direita. Análoga à subtração em decimal, observando-se que vem 1 da "casa" da esquerda (que fica valendo 1 a menos) quando o algarismo do minuendo for menor que o do subtraendo. Neste caso, o 1 que veio, vem valendo 16, o qual deve ser somado ao algarismo do minuendo, para que o resultado desta adição possa ser subtraído do algarismo do subtraendo, e cujo valor máximo pode ser 15. Os resultados de cada "casa" devem ser colocados em algarismos hexadecimais (se for 10, coloca-se A; e assim por diante, até o 15, que coloca-se F). Exemplos: 1AB4 CF55 A2BC89 FFF 0 - 123 - 102D - F00F - 4 - 2 ------- ------- --------- ------- -------- 1991 BF28 A1CC7A FFB ...FFE EXERCÍCIOS PROPOSTOS EP109: F1C5 - 101 EP110: 1AD87C - FDE9 EP111: 112233 - 44556 EP112: AABBCC - DDEEF EP113: F1E2D3 - C4B5A6 EP114: FF00001 - 10000F EP115: CAFE - FACA EP116: CDF - FDC EP117: 10001 - 20001 EP118: 10000 - FFFE EP119: 0 - 9 EP120: 0 - 1A � 1-3. Arquitetura de Mainframes IBM 1-3-1 Visão Geral Com o lançamento da linha /360, a IBM introduziu o conceito de "família" de equipamentos, onde, com compatibilidade, era possível migrar de um modelo menor para qualquer maior, permitindo que se preservasse os investimentos em hardware (periféricos) e software. O principal criador da arquitetura /360 foi Gene Amdahl (1922-). Gene Amdahl A compatibilidade era fruto de diversos fatores, e um deles era a arquitetura dos equipamentos, igual em todos os modelos (exceção aos modelos com características específicas, como os modelos 44 e o 67). Essa arquitetura era a 360, que evoluiu para a arquitetura 370, que apresentava poucas modificações, a principal delas referente ao uso de memória virtual. A arquitetura 370 evoluiu para a XA (eXtended Architecture), e, desta, para a arquitetura ESA (Extended System Architecture). Vários são os elementos que compõe a arquitetura de um sistema de computação: a capacidade e a forma de endereçamento, a forma de comunicação entre o hardware e o software, o conjunto de instruções, os componentes do(s) processador(es), etc... Alguns desses elementos são: o sistema de interrupções os "clocks" os subsistemas de entrada e saída o sistema de proteção de memória o sistema de memória virtual a forma de comunicação entre hardware e software � Um sistema mainframe IBM tem, entre outros, os seguintes componentes: Memória: é um componente fundamental, e é constituída por bytes, cada qual com 8 bits. 16 registradores gerais (ou registradores de ponto fixo), cada qual com 4 bytes 16 registradores de controle, cada qual com 4 bytes 4 registradores de ponto flutuante, cada qual com 8 bytes PSW atual : registrador especial com 8 bytes; nela existem dois "campos" importantes: um (com 3 ou 4 bytes e) que contem um endereço (vide item seguinte) que corresponde ao endereço da próxima instrução que deve ser executada, e outro com o CONDITION CODE, com 2 bits, que indica, após a execução de algumas instruções, alguma condição referente à execução da instrução, como por exemplo, o resultado de comparações. LAYOUT DA PSW ATUAL (BC MODE) BYTE 0 BITS 0-5 = máscaras de canal BIT 6 = máscara para canais 6 e acima BIT 7 = máscara externa BYTE 1 BITS 8-11 = chave de proteção BIT 12 = 0 = Basic Control Mode BIT 13 = máscara de machine-check BIT 14 = 1 = estado de wait BIT 15 = 1 = estado de programa problema BYTES 2-3 (BITS 16-31) = Interruption code BYTE 4 BITS 32-33 = ILC = Instruction length code BITS 34-35 = CC = Condition code BITS 36-39 = máscara de programa BYTES 5-7 (BITS 40-63) = Instruction address LAYOUT DA PSW ATUAL (EC MODE) BYTE 0 BIT 0 = 0 BIT 1 = máscara de program-event recording BIT 2 = 0 BIT 3 = 0 BIT 4 = 0 BIT 5 = translation mode BIT 6 = máscara de I/O BIT 7 = máscara externa BYTE 1 BITS 8-11 = chave de proteção BIT 12 = 1 = Extended Control Mode BIT 13 = máscara de machine-check BIT 14 = 1 = estado de wait BIT 15 = 1 = estado de programa problema BYTE 2 BIT 16 = 0 BIT 17 = 0 BITS 18-19 = CC = condition code BITS 20-23 = máscara de programa BIT 20 = máscara de fixed-point overflow BIT 21 = máscara de decimal-overflow BIT 22 = máscara de exponent underflow BIT 23 = máscara de significância BYTE 3 (BITS 24-31) = 00000000 BYTE 4 (BITS 32-39) = 00000000 BYTES 5-7 (BITS 40-63) = Instruction address � LAYOUT DA PSW ATUAL (XA MODE) BYTE 0 BIT 0 = 0 BIT 1 = máscara de program-event recording BIT 2-4 = 000 BIT 5 = translation mode BIT 6 = máscara de I/O BIT 7 = máscara externa BYTE 1 BITS 8-11 = chave de proteção BIT 12 = 1 BIT 13 = máscara de machine-check BIT 14 = 1 = estado de wait BIT 15 = 1 = estado de programa problema BYTE 2 BIT 16 = address space mode (junto c/ bit 5) BIT 17 = 0 BITS 18-19 = CC = condition code BITS 20-23 = máscara de programa BIT 20 = máscara de fixed-point overflow BIT 21 = máscara de decimal-overflow BIT 22 = máscara de exponent underflow BIT 23 = máscara de significância BYTE 3 (BITS 24-31) = 00000000 BYTE 4 BIT 32 = 0 = 24 bit addressing = 1 = 31 bit addressing BYTE 4/5/6/7 (BITS 33-63) = Instruction address LAYOUT DA PSW ATUAL (ESA MODE) BYTE 0 BIT 0 = 0 BIT 1 = máscara de program-event recording BIT 2-4 = 000 BIT 5 = translation mode BIT 6 = máscara de I/O BIT 7 = máscara externa BYTE 1 BITS 8-11 = chave de proteção BIT 12 = 1 BIT 13 = máscara de machine-check BIT 14 = 1 = estado de wait BIT 15 = 1 = estado de programa problema BYTE 2 BIT 16-17 = address space control = 00 = Primary space mode (bit 5 = 1) = 01 = Access-register mode (bit 5 = 1) = 10 = Secondary space mode (bit 5 = 1) = 11 = Home space mode (bit 5 = 1) BITS 18-19 = CC = condition code BITS 20-23 = máscara de programa BIT 20 = máscara de fixed-point overflow BIT 21 = máscara de decimal-overflow BIT 22 = máscara de exponent underflow BIT 23 = máscara de significância BYTE 3 (BITS 24-31) = 00000000 BYTE 4 BIT 32 = 0 = 24 bit addressing = 1 = 31 bit addressing BYTE 4/5/6/7 (BITS 33-63) = Instruction address � 1-3-2 Endereçamento Cada byte de memória tem um número que o identifica e o individualiza. A esse número dá-se o nome de endereço, e é expresso através do sistema de numeração hexadecimal. Para as arquiteturas anteriores à XA, o endereço de um byte era um número hexadecimalde 6 algarismos (24 algarismos binários - 24 bits), variando, portanto, de 000000 até FFFFFF, o que possibilitava referências a endereços até 16MB. A partir da arquitetura XA, o endereço máximo possível é de 31 bits, equivalentes a 8 algarismos hexadecimais menos 1 bit (31 algarismos binários = 31 bits); pode haver, portanto, referências a endereços que vão desde 00000000 até 7FFFFFFF, possibilitando a utilização de até 2 GB. No entanto, para que uma instrução possa fazer referência a endereços de campos de memória com os quais ela trabalhe, e para que isso seja feito de forma mais econômica (se uma instrução precisasse fazer referência a dois endereços de memória de 31 bits, ela precisaria - só para isso - de 62 bits, ou seja, praticamente 8 bytes), convencionou-se que as referências a endereços em instruções seriam feitas de forma indireta (Base + Deslocamento ou Base + Deslocamento + Indexador). BASE + DESLOCAMENTO Consiste na citação do número (endereço) de um dos 16 registradores gerais (que são endereçados de 0 a F - por serem 16), além de outro número hexadecimal composto sempre de 3 algarismos. O registrador geral usado com essa finalidade recebe o nome de registrador BASE, e o número hexadecimal complementar recebe o nome de DESLOCAMENTO. O endereço desejado é obtido através da soma entre o número contido no registrador base e o deslocamento. Nas arquiteturas anteriores à XA, o conteúdo do registrador (que tem 4 bytes = 8 algarismos hexadecimais) tem o primeiro byte à esquerda desprezado, e é levado em consideração somente o número formado pelos 3 bytes à direita. Nas outras arquiteturas, o conteúdo do registrador base tem seu primeiro bit à esquerda desprezado, e os 31 bits restantes formam um número que é levado em consideração no cálculo do endereço. Vejamos o seguinte exemplo: Caso uma instrução referencie um endereço na forma BASE + DESLOCAMENTO, onde o registrador base é o registrador geral 12, e o deslocamento é o número C5A, temos que (supondo que o conteúdo do registrador 12 seja 610AB428): Conteúdo do registrador Base = 0AB428 ou 610AB428 Deslocamento = C5A C5A Endereço do campo de memória = 0AC082 610AC082 dependendo da arquitetura utilizada. � INDEXADOR + BASE + DESLOCAMENTO que consiste na citação do número (endereço) de dois dos 16 registradores gerais, além do deslocamento. Um dos registradores gerais usado recebe o nome de registrador INDEXADOR, e o outro de registrador BASE; e o número hexadecimal complementar recebe o nome de DESLOCAMENTO. O endereço desejado é obtido através da soma com 3 parcelas: o número contido no registrador indexador, o número contido no registrador base e o deslocamento. Vale aqui as mesmas considerações anteriores relativas ao tratamento do conteúdo do registrador base (24 ou 31 bits) e elas se estendem também ao número contido no registrador indexador. Vejamos o seguinte exemplo: Caso uma instrução referencie um endereço na forma INDEXADOR + BASE + DESLOCAMENTO, em que o registrador indexador é o 8, o registrador base é o registrador 2, e o deslocamento é o número F84, temos que (supondo que o conteúdo do registrador 8 seja 30C0A800 e que o conteúdo do registrador 2 seja 10002800): Conteúdo do registrador indexador = C0A800 ou 30C0A800 Conteúdo do registrador Base = 002800 ou 10002800 Deslocamento = F84 F84 Endereço do campo de memória = C0DF84 ou 40C0DF84 dependendo da arquitetura utilizada. Exemplo de uso: endereçar itens de tabela. Endereço inicial da tabela : Símbolo = TABUFS (transformado pelo montador em base + deslocamento) Endereço do item desejado (8o) = Endereço inicial da tabela + [ tamanho de 1 item * ( quantidade itens – 1) ] = TABUFS + [ 2 * (8 – 1) ] = TABUFS + 2 * 7 = TABUFS + 14 Endereço do item desejado (8o) = Base+deslocamento de TBUFS + Registrador Indexador (ex.: 17C0A = Indexador=1, Base = 7, deslocamento = C0A) Endereço de TABUFS = na instrução, na forma Base + deslocamento (montador coloca); supor Base=7 e deslocamento = X’C0A’ Conteúdo reg. Indexador = registrador 1 (responsabilidade de nosso programa colocar) com conteúdo X’0000000E’ � IMPORTANTE : se o registrador base ou o registrador indexador for o registrador 0, o seu conteúdo é desprezado no cálculo do endereço. Exemplos: 1) Registrador indexador = R0; conteúdo = 00345CB9 Registrador base = R7; conteúdo = 00FCD800 Deslocamento = 12A Endereço de memória = 00FCD92A 2) Registrador indexador = R9; conteúdo = 00345CB9 Registrador base = R0; conteúdo = 00FCD800 Deslocamento = 12A Endereço de memória = 00345DE3 3) Registrador indexador = R0; conteúdo = 00345CB9 Registrador base = R0; conteúdo = 00FCD800 Deslocamento = 12A Endereço de memória = 0000012A 4) Registrador base = R0; conteúdo = 00334400 Deslocamento = 123 Endereço de memória = 00000123 5) Registrador base = R9; conteúdo = 00334400 Deslocamento = 123 Endereço de memória = 00334523 Deslocamento máximo; uso de bases Por poder ser representado em 1 byte e meio, o deslocamento máximo é X’FFF’ (4095 bytes). Ou seja: se o registrador base tiver x’00000000’ como conteúdo, ele só consegue ser usado como base para fazer referência aos endereços desde x’00000000’ até x’00000FFF’ (endereçamento base+deslocamento). Se uma instrução precisar endereçar 2 campos na forma base+deslocamento: - um deles com endereço x’00000048’ e outro com endereço x’00001CB0’, na hora em que ela for executada, ela precisa mais do que um registrador base preparado convenientemente. Pode-se, por exemplo, ter o registrador C com o conteúdo x’00000000’, e outro registrador (o D, por exemplo) com o conteúdo x’00001000’. O registrador base C (12) endereça o primeiro campo: Base+deslocamento = C048 = Base C (com conteúdo x’00000000’) + Deslocamento x’048’ O registrador base D (13) endereça o segundo campo Base+deslocamento = DCB0 = Base D (com conteúdo x’00001000’) + Deslocamento x’CB0’ Não há como, em uma única instrução, neste caso, usar só um registrador base. Como o registrador zero não é considerado no cálculo de endereços, pode-se usar no máximo 15 registradores base. Como cada base consegue endereçar 4096 bytes (desde o byte cujo endereço é o valor do registrador base +0 até o byte cujo endereço é o valor do registrador base + X’FFF’). Isso significa que 1 registrador base consegue endereçar um conjunto de 4K bytes de memória. Com no máximo 15 registradores base: 15 registradores X 4K cada = Máximo de 60K endereçáveis. Caso o programa seja maior que isso, deve-se dividir o programa em blocos separados, e cada bloco ser “servido” por um conjunto de registradores base, que serão reutilizados (com outros conteúdos), nos demais blocos. Uma sugestão: Pensar em quais serão os registradores bases do programa inteiro, e quais serão os registradores de trabalho. Segue tabela com sugestão para uso dos 16 registradores: 0 = Evitar; usado pelas rotinas dos métodos de acesso e Sist. Op. 1 = Evitar; usado pelas rotinas dos métodos de acesso e Sist. Op. Usado pelas instruções TRT e EDMK 2 = Evitar se necessário ou usar para work; usado pela instrução TRT de edição 3 = Usar como base 4 = Usar como base 5 = Usar como base 6 = Usar como base 7 = Usar como base 8 = Usar como work 9 = Usar como work 10 = Usar como work 11 = Usar como work 12 = Usar como work 13 = Evitar; usado como base de área de salvação de saveareas nos processosde interface entre softwares 14 = Evitar; usado em geral como “guardador” do endereço de volta do programa chamador. 15 = Evitar; usado em geral como pointer para efetuar algum desvio para programa chamado Neste caso, há 5 registradores usados como base: R3, R4, R5, R6 e R7 Isso permite endereçar (5 x 4K) = 20K no máximo. Supondo um programa de 60K dividido em 3 trechos (blocos) de 20K cada um, em cada bloco podemos carregar os bases e usar só coisas (instruções e áreas) desse trecho. Resumo São endereçados : registradores e bytes de memória (Lembrar que o endereço de um campo de memória é o endereço de seu byte mais à esquerda) Só existe endereçamento DIRETO para registradores: Registradores Gerais = 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F Registradores de Ponto Flutuante = 0,2,4,6 Não existe endereçamento DIRETO para memória. O endereçamento INDIRETO de memória pode ser: - Base + Deslocamento - Indexador + Base + Deslocamento Base + Deslocamento Endereço = Número hexadecimal resultante da soma entre o Número binário contido num Registrador Geral (registrador que nesta hora é chamado de registrador base) + Número hexadecimal contido na instrução, de x’000’ até x’FFF’ “apelidado” de deslocamento Indexador + Base + Deslocamento Endereço = Número hexadecimal resultante da soma entre o Número binário contido num Registrador Geral (registrador que nesta hora é chamado de registrador indexador) + Número binário contido num Registrador Geral (registrador que nesta hora é chamado de registrador base) + Número hexa contido na instrução, de x’000’ até x’FFF’ “apelidado” de deslocamento Carga de registradores base Apesar de não termos visto ainda as instruções, fica aqui neste ponto o registro de como é geralmente feita a preparação do conteúdo dos registradores base. Após ver as instruções BALR, BCTR, LA e L, volte a este ponto para entender como na prática, na maior parte das vezes, é feita a carga do(s) registrador(es) base. Carga de 1 único registrador base PROG START 0 USING *,3 LR 3,15 CARREGA PRIMEIRO E UNICO REG BASE * REG 3 FICA COM O ENDERECO DO ENTRY POINT * CARREGAMENTO COM LR MUITO USADO EM MVS ou PROG START 0 USING *,3 BALR 3,0 CARREGA ENDERECO SEGUINTE AO BALR BCTR 3,0 SUBTRAI 1 BCTR 3,0 SUBTRAI MAIS 1 * NESTE PONTO, O REG 3 ESTAH OK; * ELE TEM O ENDERECO DO ENTRY POINT Carga de 2 registradores base Pode fazer assim? PROG START 0 USING *,3,4 LR 3,15 CARREGA PRIMEIRO REG BASE * REG 3 FICA COM O ENDERECO DO ENTRY POINT LA 4,4096(4) CARREGA NO 4 O QUE TEM NO 3 + 4096 Não! Por que? Porque o deslocamento máximo é de 4095 (X’FFF’) !!! Dá erro de montagem ! Então tem que fazer assim: PROG START 0 USING *,3,4 LR 3,15 CARREGA PRIMEIRO REG BASE * REG 3 FICA COM O ENDERECO DO ENTRY POINT LA 4,1 CARREGA NRO 1 NO REG 4 LA 4,4095(4) SOMA 4095 * FICOU COM 4096 AR 4,3 SOMA O ENTRY POINT. * FICOU ENTRY POINT + 4096 * OU ENTRY POINT + X’001000’ * PRONTO ! R4 CARREGADO OK TAMBEM ! Ou assim: PROG START 0 USING *,3,4 LR 3,15 CARREGA PRIMEIRO REG BASE * REG 3 FICA COM O ENDERECO DO ENTRY POINT LA 4,4095 CARREGA NRO 4095 NO REG 4 LA 4,1(4) SOMA 1 * FICOU COM 4096 AR 4,3 SOMA O ENTRY POINT. * FICOU ENTRY POINT + 4096 * OU ENTRY POINT + X’001000’ * PRONTO ! R4 CARREGADO OK TAMBEM ! Até assim: PROG START 0 USING *,3,4 LR 3,15 CARREGA PRIMEIRO REG BASE * REG 3 FICA COM O ENDERECO DO ENTRY POINT LA 4,1 CARREGA NRO 1 NO REG 4 LA 4,4095(3,4) SOMA 4095 + ENTRY POINT * FICOU COM ENTRY POINT + 4096 * OU ENTRY POINT + X’001000’ * PRONTO ! R4 CARREGADO OK TAMBEM ! Desse jeito: PROG START 0 USING *,3,4 LR 3,15 CARREGA PRIMEIRO REG BASE * REG 3 FICA COM O ENDERECO DO ENTRY POINT LA 4,2048 CARREGA NRO 2048 NO REG 4 LA 4,2048(3,4) SOMA 2048 + ENTRY POINT * FICOU COM ENTRY POINT + 4096 * OU ENTRY POINT + X’001000’ * PRONTO ! R4 CARREGADO OK TAMBEM ! � Deste jeitinho... PROG START 0 USING *,3,4 LR 3,15 CARREGA PRIMEIRO REG BASE * REG 3 FICA COM O ENDERECO DO ENTRY POINT LA 4,1000 CARREGA NRO 1000 NO REG 4 LA 4,3096(3,4) SOMA 3096 + ENTRY POINT * FICOU COM ENTRY POINT + 4096 * OU ENTRY POINT + X’001000’ * PRONTO ! R4 CARREGADO OK TAMBEM ! Será que pode fazer assim? PROG START 0 USING *,3,4 LR 3,15 CARREGA PRIMEIRO REG BASE * REG 3 FICA COM O ENDERECO DO ENTRY POINT LA 4,PROG+4096 CARREGA “DIRETO” ENTRY POINT + 4096 NÃO! Por que não? Porque o endereço PROG+40096 não está no alcance do primeiro base (R3), até então o único carregado corretamente. Dá erro de montagem. Nem assim? PROG START 0 USING *,3,4 LR 3,15 CARREGA PRIMEIRO REG BASE * REG 3 FICA COM O ENDERECO DO ENTRY POINT L 4,=A(PROG+4096) CARREGA “DIRETO” ENTRY POINT + 4096 DEPENDE ! O que está sendo carregado no R4 é o conteúdo da literal. (Situação 1) Se a literal estiver dentro do alcance do PRIMEIRO REG BASE (R3), QUE É O ÚNICO PREPARADO ATÉ ENTÃO, então PODE. (Situação 2) Senão, NÃO PODE! Dá erro de montagem. Situação 1 Situação 2 Uma visão esquemática da questão dos registradores base. Caso 1 Supor um programa com 11K de tamanho e 1 registrador base. PROG START 0 USING *,3 Using quando o location counter tem zero LR 3,15 CARREGA PRIMEIRO E UNICO REG BASE ... � Caso 2 Supor um programa com 11K de tamanho e 2 registradores base. PROG START 0 USING *,3 Using quando o location counter tem zero LR 3,15 CARREGA PRIMEIRO REG BASE LA 7,1 LA 7,4095(3,7) ... Caso 3 Supor um programa com 11K de tamanho e 3 registradores base. PROG START 0 USING *,3 Using quando o location counter tem zero LR 3,15 CARREGA PRIMEIRO REG BASE LA 7,1 LA 7,4095(3,7) LA 6,1 LA 6,4095(6,7) ... Caso 4 Supor um programa com 1000K de tamanho e 1 registrador base. PROG START 0 USING *,3 Using quando o location counter tem zero LR 3,15 CARREGA PRIMEIRO E UNICO REG BASE ... Caso 5 Supor um programa com 1000K de tamanho e 1 registrador base. PROG START 0 USING *,3 Using quando o location counter tem zero LR 3,15 CARREGA PRIMEIRO E UNICO REG BASE ... Caso 6 Supor um programa com 1000K de tamanho e 1 registrador base. PROG START 0 USING *,3 Using quando o location counter tem zero LR 3,15 CARREGA PRIMEIRO E UNICO REG BASE ... Caso7 Supor um programa com 1000K de tamanho e 1 registrador base. PROG START 0 USING *,3 Using quando o location counter tem zero LR 3,15 CARREGA PRIMEIRO E UNICO REG BASE ... Detalhando o trecho servido pelo registrador base R3 e o início do trecho sem registrador base; a parte sombreada é aquela servida pelo registrador base, e a parte sem sombra é aquela que não é servida pelo registrador base: Neste caso, estão DENTRO do alcance do registrador base: as instruções as áreas antes do LTORG as literais o início das áreas grandes (especificamente os primeiros 100 bytes de TABXX) E estão FORA do alcance do registrador base: os 499900 bytes seguintes de TABXX os 520000 bytes de TABYY e os 4 bytes de XYZ Isto significa que: LA R9,TABXX OK! TABXX (o endereço de TABXX é o endereço de seu primeiro bytes à esquerda) está dentro do alcance do registrador base L R9,=A(TABXX) OK! A literal que tem o endereço de TABXX está dentro do alcance do registrador base LA R9,TABXX+1 OK! TABXX+1 é um endereço que está dentro do alcance do registrador base L R9,=A(TABXX+1) OK! A literal que tem o endereço de TABXX+1 está dentro do alcance do registrador base LA R9,TABXX+99 OK! TABXX+99 é um endereço que está dentro do alcance do registrador base L R9,=A(TABXX+99) OK! A literal que tem o endereço de TABXX+99 está dentro do alcance do registrador base LA R9,TABXX+100 ERRO!!! TABXX+100 é o 101º. Byte de TABXX, e, portanto, o primeiro a NÃO ser servido pelo registrador base L R9,=A(TABXX+100) OK! A literal que tem o endereço de TABXX+100 está dentro do alcance do registrador base LA R9,TABYY ERRO!!! TABYY é um endereço que NÃO está dentro do alcance do registrador base L R9,=A(TABYY) OK! A literal que tem o endereço de TABYY está dentro do alcance do registrador base LA R9,XYZ ERRO!!! XYZ é um endereço que NÃO está dentro do alcance do registrador base L R9,=A(XYZ) OK! A literal que tem o endereço de XYZ está dentro do alcance do registrador base � 1-3-3 Representação de Dados Os dados podem ser representados de forma codificada, em formato que depende de sua natureza. Assim, devemos distinguir os dados numéricos dos alfanuméricos. Os dados numéricos podem ser representados numa das seguintes formas: - Formato binário de ponto flutuante - Formato binário de ponto fixo - Formato decimal zonado - Formato decimal compactado Os dados alfanuméricos devem ser representados no formato EBCDIC. 1-3-3-1 Formato binário de ponto fixo Neste caso, deve-se usar campos de memória que sejam: - Half-words (campos de 2 bytes com endereço múltiplo de 2) - Full-words ou simplesmente words (campos de 4 bytes com endereço múltiplo de 4). Os números são representados usando-se 15 bits (se for numa half-word) ou 31 bits (se for numa full-word); o bit adicional é usado para indicar o sinal do número, e é o primeiro bit à esquerda do campo. Exemplos: Número Representação em Half-word Representação em Full-word +12 00.0C 00.00.00.0C -12 FF.F4 FF.FF.FF.F4 � 1-3-3-2 Formato decimal zonado Neste caso, cada algarismo do número decimal ocupa um byte, tendo na parte de zona a configuração F (o último byte à direita é exceção), e na parte numérica a configuração correspondente ao algarismo desejado. No último byte à direita, a parte de zona tem configuração correspondente ao sinal do número: C ou F se o número for positivo, ou D se o número for negativo. Se for necessário usar campos maiores que o suficiente para conter o número desejado, deve-se ter zeros zonados à esquerda. O maior tamanho possível é de 16 bytes. Exemplos: Número Representação em decimal zonado +12 F1.C2 ou F1.F2 -12 F1.D2 1-3-3-3 Formato decimal compactado Neste caso, cada algarismo do número decimal ocupa meio byte, tendo na parte numérica do último byte à direita a configuração correspondente ao sinal do número: C ou F se o número for positivo, ou D se o número for negativo. Se for necessário usar campos maiores que o suficiente para conter o número desejado, deve-se ter zeros à esquerda. O maior tamanho possível é de 16 bytes. Exemplos: Número Representação em decimal compactado +12 01.2C ou 01.2F -12 01.2D 1-3-3-4 Formato caractere (padrão EBCDIC) Cada caractere ocupa 1 byte. Se o campo for maior, geralmente o preenchimento é à direita com espaços. Um conjunto de caracteres recebe o nome de “string”. Exemplos: String Representação em EBCDIC ALBERTO C1.C3.D2.C5.D9.E4.D6 Alberto C1.93.82.85.99.A4.96 AMO ELA C1.C4.D6.40.C5.D3.C1 +12 4E.F1.F2 -12 60.F1.F2 A título de curiosidade, a representação desses mesmos strings no padrão ASCII é a seguinte: String Representação em ASCII ALBERTO 41.4C.42.45.52.54.4F Alberto 41.6C.62.65.72.74.6F AMO ELA 41.4D.4F.20.45.4C.41 +12 2B.31.32 -12 2D.31.32 � 1-3-4 Representação de Instruções Existem os seguintes tipos de instruções: RR - 2 bytes CO = 1 byte (código de operação) R1 = 1/2 byte (registrador primeiro operando) R2 = 1/2 byte (registrador segundo operando) E - 2 bytes ambos para o código de operação QST - 4 bytes CO = 2 bytes (código de operação) QR3 = 1/2 byte (registrador geral -GR- ou pto flut -FR- terceiro oper) RT2 = 1/2 byte (registrador "stride of vector" do segundo operando) VR1 = 1/2 byte (registrador de vetor primeiro operando) RS2 = 1/2 byte (registrador end início de vetor do segundo operando) QV - 4 bytes CO = 2 bytes (código de operação) QR3 = 1/2 byte (registrador geral -GR- ou pto flut -FR- terceiro oper) NU = 1/2 byte (não usado) VR1 = 1/2 byte (registrador de vetor primeiro operando) VR2 = 1/2 byte (registrador de vetor segundo operando) RRE - 4 bytes CO = 2 bytes (código de operação) NU = 1 byte (não usado) R1 = 1/2 byte (registrador primeiro operando) R2 = 1/2 byte (registrador segundo operando) RS - 4 bytes CO = 1 byte (código de operação) R1 = 1/2 byte (registrador primeiro operando) R3 = 1/2 byte (registrador terceiro operando) B2 = 1/2 byte (registrador base do segundo operando) D2 = 1 byte e 1/2 (deslocamento do segundo operando) RX - 4 bytes CO = 1 byte (código de operação) R1 = 1/2 byte (registrador primeiro operando) X2 = 1/2 byte (registrador indexador do segundo operando) B2 = 1/2 byte (registrador base do segundo operando) D2 = 1 byte e 1/2 (deslocamento do segundo operando) S - 4 bytes CO = 2 bytes (código de operação) B2 = 1/2 byte (registrador base do segundo operando) D2 = 1 byte e 1/2 (deslocamento do segundo operando) SI - 4 bytes CO = 1 byte (código de operação) I2 = 1 byte (operando imediato - segundo operando) B1 = 1/2 byte (registrador base do primeiro operando) D1 = 1 byte e 1/2 (deslocamento do primeiro operando) VR - 4 bytes CO = 2 bytes (código de operação) QR3 = 1/2 byte (registrador geral -GR- ou pto flut -FR- terceiro oper) NU = 1/2 byte (não usado) VR1 = 1/2 byte (registrador de vetor primeiro operando) GR2 = 1/2 byte (registrador segundo operando) VS - 4 bytes CO = 2 bytes (códigode operação) NU = 1 byte e 1/2 (não usado) RS2 = 1/2 byte (registrador end início de vetor do segundo operando) VST - 4 bytes CO = 2 bytes (código de operação) VR3 = 1/2 byte (registrador de vetor terceiro operando) RT2 = 1/2 byte (registrador "stride of vector" do segundo operando) VR1 = 1/2 byte (registrador de vetor primeiro operando) RS2 = 1/2 byte (registrador end início de vetor do segundo operando) VV - 4 bytes CO = 2 bytes (Código de operação) VR3 = 1/2 byte (registrador de vetor terceiro operando) NU = 1/2 byte (não usado) VR1 = 1/2 byte (registrador de vetor primeiro operando) VR2 = 1/2 byte (registrador de vetor segundo operando) RSE - 6 bytes CO = 2 bytes (código de operação) R3 = 1/2 byte (registrador terceiro operando) NU = 1/2 byte (não usado) VR1 = 1/2 byte (registrador de vetor primeiro operando) NU = 1/2 byte (não usado) B2 = 1/2 byte (registrador base do segundo operando) D2 = 1 byte e 1/2 (deslocamento do segundo operando) SS - 6 bytes CO = 1 byte (código de operação) o segundo byte pode ter uma das 3 alternativas: . R1 = 1/2 byte (registrador primeiro operando) R3 = 1/2 byte (registrador terceiro operando) ou . L1 = 1/2 byte (tamanho - 1 do primeiro operando) L2 = 1/2 byte (tamanho - 1 do segundo operando) ou . L = 1 byte (tamanho - 1 dos dois operandos) B1 = 1/2 byte (registrador base do primeiro operando) D1 = 1 byte e meio (deslocamento do primeiro operando) B2 = 1/2 byte (registrador base do segundo operando) D2 = 1 byte e meio (deslocamento do segundo operando) SSE - 6 bytes CO = 2 bytes (código de operação) B1 = 1/2 byte (registrador base do primeiro operando) D1 = 1 byte e meio (deslocamento do primeiro operando) B2 = 1/2 byte (registrador base do segundo operando) D2 = 1 byte e meio (deslocamento do segundo operando) � EXERCÍCIOS PROPOSTOS Representar, no formato binário de ponto fixo, em half-words e full-words, os seguintes números (especificados em decimal): EP121: 1 EP122: -1 EP123: 10 EP124: -10 EP125: 17 EP126: -17 EP127: 254 EP128: -254 EP129: 100000 EP130: -100000 EP131: 32000 EP132: -32000 EP133: 63000 EP134: -63000 EP135: 1010 EP136: -1010 EP137: 4095 EP138: -4095 EP139: 4097 EP140: -4097 � Representar, no formato decimal compactado, os seguintes números (especificados em decimal): EP141: 1 EP142: -1 EP143: 10 EP144: -10 EP145: 17 EP146: -17 EP147: 254 EP148: -254 EP149: 100000 EP150: -100000 EP151: 32000 EP152: -32000 EP153: 63000 EP154: -63000 EP155: 1010 EP156: -1010 EP157: 4095 EP158: -4095 EP159: 4097 EP160: -4097 � Representar, no formato decimal zonado, os seguintes números (especificados em decimal): EP161: 1 EP162: -1 EP163: 10 EP164: -10 EP165: 17 EP166: -17 EP167: 254 EP168: -254 EP169: 100000 EP170: -100000 EP171: 32000 EP172: -32000 EP173: 63000 EP174: -63000 EP175: 1010 EP176: -1010 EP177: 4095 EP178: -4095 EP179: 4097 EP180: -4097 � Representar, no formato EBCDIC, os seguintes dados: EP181: 17 EP182: -17 EP183: AF$BD EP184: -AF4BD EP185: ALBERTO EP186: 15-9 EP187: -4095 EP188: 4095 EP189: *&$// EP190: 12+3 EP191: EU E ELA EP192: CR$ 2.584,73 EP193: US$ 1 MILHAO EP194: TICO'S BAR � 2. Montador Assembler e Especificação de Elementos 2-1. Introdução 2-1-1 O Montador Assembler É o programa encarregado de transformar as instruções de linguagem fonte (simbólica) para linguagem objeto. O programa objeto será posteriormente tratado pelo linkeditor para torná-lo executável. Uma das diferenças básicas entre um montador e um compilador é que o montador, para cada instrução simbólica gera uma única instrução de máquina, ao passo que um compilador pode gerar de uma a n instruções de máquina. Numa primeira fase, o montador Assembler lê todos os statements fonte, expandindo as macro-instruções e os COPY's, e, além disso, identificando todos os comandos ao montador e instruções de máquina; ele consegue, para cada um deles que gera algum byte, identificar quantos bytes devem ser gerados, e, em alguns casos, já colocando o conteúdo necessário do programa objeto. À medida que vai alocando os bytes, o montador Assembler vai incrementando um contador denominado LOCATION COUNTER, que reflete a quantidade de bytes gastos (alocados) até um determinado instante, isto é, o tamanho do programa até esse instante. Ao mesmo tempo, cada símbolo encontrado vai formando a TABELA DE SÍMBOLOS, de tal forma que fique completa ao fim da primeira fase. A tabela de símbolos contém, entre outras informações: o símbolo, seu endereço, seu atributo de tamanho e seu atributo de tipo (se é uma instrução, o atributo de tipo é I, se é um campo compactado, o atributo de tipo é P, se for uma full-word, é F, e assim por diante). Na segunda fase, de posse da tabela de símbolos completa, ele "varre" o código objeto gerado, completando as informações que tinham ficado faltando, como por exemplo os endereços na forma base + deslocamento. Para efeito de exemplificação, vejamos o seguinte fluxo, referente ao sistema operacional MVS: � fonte objeto SYSIN SYSPUNCH macros/ asmF=IFOX00 listagem copys SYSLIB asmH=IEV90 SYSPRINT work objeto SYSUT1 SYSGO objeto SYSUT1 SYSLIN statements listagem de contro- IEWL le SYSPRINT SYSINoutros executável objetos SYSLMOD SYSLIB executável (de uma LOADER memória LINKLIB) � 2-1-2 O Statement Assembler Ele é utilizado para a codificação das instruções de um programa em Assembler. Normalmente (pode ser diferente - veja o comando ICTL) um statement Assembler é dividido em campos, cada um com uma função. São os seguintes os campos: a) Posições 1 a 8: Símbolo b) Posições 10 a 14: Código da Instrução c) Posições 16 a 71: Operandos e Comentários d) Posição 72: Posição de Continuação e) Posições 73 a 80: Identificação e Sequência COMPLETA MVC ARIMP,=CL133'b' LIMPAR ARIMP Os operandos são separados um do outro por vírgula. Símbolo (se houver) e instrução devem ser separados por pelo menos 1 espaço em branco. Instrução e operandos (se houver) devem ser separados por pelo menos 1 espaço em branco. Comentários (se houver) devem ser separados dos operandos por pelo menos 1 espaço em branco. Estudemos mais detalhadamente cada um desses campos: 2-2. Símbolo Também conhecido como LABEL. É o nome que se atribui a uma Instrução ou de uma área. Para a criação de um símbolo, deve-se obedecer às seguintes regras: Um símbolo pode ter de 1 a 8 caracteres (no Assembler F) ou de 1 a 63 caracteres (no Assembler H) Os caracteres válidos para a formação de símbolos são: - Letras: A até Z - Algarismos: 0 ate 9 - Caracteres $ @ # O primeiro caractere não pode ser um algarismo Exemplos de símbolos válidos: ARIMP ARLEIT TOTAL3 VALOR$ $VALOR SOMAR7 A Exemplos de símbolos não-válidos (o segundo é válido no Assembler H): 3TOTAL TRANZAMAZONICA EU E ELA EU-E-ELA CABEC. � 2-3. Código de Instrução Especifica a instrução. Pode-se especificar um dos 3 tipos: 2-3-1 Instruções ao Montador São dados para o montador Assembler, a fim de conduzir a montagem de acordo com o necessário. Com poucas exceções, elas não dão origem a nenhuma instrução em linguagem de máquina. São os seguintes os Comandos ao Montador Assembler: a) Definição de áreas : DC, DS, CCW, CCW0, CCW1 b) Seccionamento de um Programa e Ligação: START, CSECT, DSECT, DXD CXD, COM, ENTRY, EXTRN, WXTRN c) Controle de Registradores Base: USING, DROP d) Controle da listagem: TITLE, EJECT, SPACE, PRINT e) Controle de programa : ICTL, ISEQ, PUNCH, REPRO, ORG, EQU, OPSYN, PUSH POP, LTORG, CNOP, COPY, END, LOCTR, AMODE, RMODE f) Definição de macro-instrução: AREAD, MACRO, MEXIT, MEND g) Montagem condicional: ACTR, AGO, AIF, ANOP, GBLA, GBLB, GBLC LCLA, LCLB, LCLC, MHELP, MNOTE, SETA, SETB, SETC 2-3-2 Instruções de Máquina Para cada código de operação válido no primeiro byte de uma instrução de máquina, existe um código Assembler correspondente. Verifique nos APÊNDICES A e B a relação de todas as instruções de máquina. 2-3-3 Macro-Instruções São códigos que farão com que o montador Assembler dê origem a diversas instruções (de máquina ou ao montador). Para que ele saiba o que gerar, ele consulta a Biblioteca de Macros (em VSE é a SOURCE STATEMENT LIBRARY; em MVS é, em geral, a SYS1.MACLIB). As macro-instruções variam de um sistema operacional para outro. 2-4. Operandos e Comentários Os operandos informam onde se localizam os dados a serem processados. Deve-se especificar um operando após o outro, separando-os através de uma vírgula, sem espaços em branco. Terminada a especificação dos operandos, deve haver pelo menos um espaço em branco; o que vier em seguida, até a posição 71, será considerado comentário, isto é, servirá somente para, aparecendo na listagem dos statements-fonte fornecida pelo montador, explicar o que foi feito na instrução. Por exemplo: Os operandos de uma instrução podem ser registradores ou campos de memória. Vejamos agora, como, ao escrevermos uma instrução, especificamos um operando. 2-4-1 Operandos em Registrador Este é o caso mais simples; deve-se apenas colocar o número do registrador que contém o dado a ser processado. Suponha, por exemplo, que você tenha um número no registrador 7, e queira adicionar a ele outro número que esteja no registrador 12. Em Assembler a instrução que efetua essa soma é AR 7,12 Sendo que AR é o código mnemônico da instrução que soma números contidos em registradores. � 2-4-2 Operandos em Memória Para que façamos referência a um operando que seja um campo de memória, utilizamo-nos de EXPRESSÕES que representam os endereços dos campos utilizados. As expressões são compostas de TERMOS, dos quais existem 5 tipos, descritos a seguir. 2-4-2-1 Termos de Expressões I - SÍMBOLOS, que podem ser de 3 tipos: Ordinários (vistos no item 2-2), Variáveis e de Sequência (serão vistos no estudo de macros). II - ATRIBUTO DE TAMANHO : O seu formato é L's, sendo que s é um símbolo. O valor deste termo será o tamanho (Length) do símbolo. Exemplo: L’WCALC indica o tamanho da variável WCALC. III - REFERÊNCIA AO LOCATION COUNTER : O montador Assembler tem para si um contador que é incrementado durante a montagem, à medida que vão sendo usados bytes, seja por instruções, seja por áreas. O nome desse contador de posições é LOCATION COUNTER, e a referência a ele (a seu conteúdo) é feita colocando-se um asterisco (*). Compreenderemos melhor através de um exemplo. Normalmente, ao ser iniciada a montagem de um programa, o conteúdo do LOCATION COUNTER é zero. Suponhamos um programa com o seguinte conjunto de instruções e de áreas: Instruções e áreas, conforme definidas no programa Tamanho de cada instrução ou área (em bytes) Conteúdo do Location Counter ANTES Conteúdo do Location Counter DEPOIS BALR 3,0 USING *,3 BAL 14,ROTLE CLC CODIGO,=C'1' BNE ERRADO AP CERTO,=P'1' BAL 14,IMPRIME . . . . CODIGO DS CL1 CERTO DC PL3'0' . 2 0 4 6 4 6 4 . . Por ex. 382 bytes . 1 3 . 000000 000002 000002 000006 00000C 000010 000016 00001A ... ... 000198 000199 00019C 000002 000002 000006 00000C 000010 000016 00001A ... ... 000198 000199 00019C ... Veja que o conteúdo do location counter é atualizado a cada instrução, a cada campo utilizado, a cada byte gasto. Note que o comando ao montador USING (segunda linha do programa) tem 2 operandos, sendo que o primeiro é uma referência ao Location Counter. � IV - TERMOS AUTO-DEFINIDOSSão termos cujo valor é inerente ao termo, isto é, eles próprios são uma especificação explícita do valor que representam. Podem ser de 4 tipos: - Decimal: um número decimal composto de 1 ate 8 algarismos. Ex: MVI BYTE,240 - Hexadecimal: um número hexadecimal composto de 1 ate 6 algarismos, colocados entre apóstrofes, e precedido da letra X. Ex: MVI BYTE,X'F0' - Binário: número binário composto de 1 ate 24 algarismos, colocados entre apóstrofes, e precedido da letra B. Ex: MVI BYTE,B'11110000' - Caractere: conjunto de 1 a 3 caracteres quaisquer colocados entre apóstrofes e precedido da letra C. Ex: MVI BYTE,C'0' OBS: Se o caractere desejado for um apóstrofe (') ou um E Comercial (&), ele deve ser colocado duas vezes. Ex: MVI BYTE,C'&&' MVI BYTE,C'''' Como vimos, os termos formam expressões cuja função é fazer referência a um operando na memória. Uma expressão pode ser composta de um ou mais termos, aritmeticamente combinados através dos sinais + adição - subtração * multiplicação / divisão e, quando necessário, de parênteses, para ordenar a sequência de resolução da expressão. Ex: ARIMP+L'SALARIO-2*(LEP02/4) 2-4-2-2 Expressões para referência de Operandos Não esqueçamos que a referência a um campo de memória tem por função informar ao montador qual o endereço do campo, para que o montador possa transformar a instrução de linguagem simbólica para linguagem de máquina, na qual o endereço é colocado na forma BASE + DESLOCAMENTO ou INDEXADOR + BASE + DESLOCAMENTO. OBS: - daqui em diante, usaremos as seguintes abreviaturas: R1 = Registrador primeiro operando R2 = Registrador segundo operando R3 = Registrador terceiro operando B1 = Registrador Base do primeiro operando B2 = Registrador Base do segundo operando D1 = Deslocamento do primeiro operando D2 = Deslocamento do segundo operando X2 = Registrador Indexador do segundo operando I2 = Operando Imediato (segundo operando) L = Tamanho do primeiro e do segundo operandos L1 = Tamanho do primeiro operando L2 = Tamanho do segundo operando CO = Código de Operação Existem três maneiras de especificarmos um operando de memória: a) EXPLÍCITA: - esta forma é para a especificação de registradores ou de operandos de memória. No caso de registrador, basta colocar o número do registrador desejado. Para operandos de memória, há uma indicação explícita de qual é o registrador indexador, qual é o registrador base e qual o deslocamento. A indicação deve ser feita do seguinte modo: a1. Instruções RX: CO R1,D2(X2,B2) CO R1,D2(X2) assume base 0 CO R1,D2(,B2) assume indexador 0 a2. Instruções RS: CO R1,R3,D2(B2) a3. Instruções SI: CO D1(B1),I2 a4. Instruções SS: (1 tamanho) CO D1(L,B1),D2(B2) a4. Instruções SS: (2 tamanhos) CO D1(L1,B1),D2(L2,B2) Exemplos dos diversos tipos: LA 7,382(3,12) RX LA 7,382(3) RX LA 7,382(,12) RX LM 1,12,35(14) RS MVI 0(5),X'80' SI MVC 0(2,7),5(11) SS (L) AP 4(8,12),0(2,3) SS (L1 e L2) b) IMPLÍCITA: - esta forma é usada, em geral, para operandos de memória; nela, é feita a indicação do endereço através de expressões, cujo valor, calculado pelo Assembler, é o endereço real do campo desejado. O montador Assembler se encarrega de transformar o endereço real para a forma base + deslocamento. Ex: LA 7,TABELA LA 7,TABELA-30 LM 1,13,SAVE+4 MVI ARIMP+82,C'*' MVI BYTE,C'*' MVC ARIMP+5(6),ARCOMP MVC ARIMP+5(6),ARCOMP+2 AP TOTAL,=P'1' AP VALOR,ARLEIT+5(2) SP ARLEIT+5(8),ARLEIT+28(3) OBS:- O número que vai entre parênteses após a expressão, indica o tamanho do operando. Numa instrução SS que faz referência a 1 tamanho, este deve ser especificado no primeiro operando; o segundo operando não pode ter indicação de tamanho. Observar que as instruções que se enquadram nesse tipo são: MVN, MVC, MVZ, NC, CLC, OC, XC, TR, TRT, ED, EDMK. � c) LITERAIS :- São áreas (constantes) definidas através das próprias instruções que delas se utilizam. Uma literal é composta do sinal de igual seguido daquilo que seria a parte de operando de um comando DC ou DS utilizado para definir a área desejada. O montador Assembler, sabendo o endereço da literal, transforma-o em base+deslocamento. Ex: MVC ARIMP,=CL133' ' CLC BYTE,=C' ' CLC =C' ', BYTE Para entender melhor, veja adiante os comandos DC e DS. 2-5. Continuação de Statements Quando, ao se escrever uma instrução, ela não couber na linha (statement), deve-se colocar qualquer caractere diferente de branco na posição 72 do statement a ser continuado, e, a partir da posição 16 (inclusive) do statement seguinte, deve-se fazer a continuação. As posições 1 a 15 do statement de continuação devem ficar obrigatoriamente em branco. Vejamos os seguintes exemplos: 123456789012345678901234567890123456789012345678901234567890123456789012 CABEC DC CL133' RELACAO DE FUNCIONARIOS COM SEUS RE- SPECTIVOS DEPENDENTES' ENTRADA DCB DSORG=PS, ORGANIZACAO - DDNAME=DDENTRA, NOME DO DD - EODAD=FIM, FIM DE ARQUIVO - MACRF=(GM) MACROS USADAS 2-6. Identificação e Sequência de Statements Em geral, usam-se essas posições da seguinte maneira: Pos. 73 a 76 - Identificação. Conjunto de 4 caracteres quaisquer que podem identificar o programa. Pos. 77 a 80 - Número sequencial do statement, em geral numerado de 10 em 10. OBS: 1) A divisão estabelecida no início do capítulo 2 não é rígida. O importante é haver pelo menos um espaço em branco entre o Símbolo e o Código de Operação; outro espaço em branco entre o Código de Operação e os operandos; e, finalmente, pelo menos um espaço em branco entre os Operandos e Comentários. 2) Quando houver um asterisco (*) na posição 1 de um statement, ele será considerado comentário. � 3. Instruções ao Montador Assembler 3-1. Instruções para definição de áreas DC (Define Constant - Definir Constante) [Símbolo] DC [A1]B1[C1]D1[,[A2]B2[C2]D2,...] A função do DC é definir uma área de memória, atribuindo a ela um conteúdo inicial. Temos que: A - Atributo de duplicação. É um número decimal que indica quantas vezes se deseja definir a área. O mínimo é 1. Se omitido, assume 1. B- Letra que indica o tipo de constante. Obrigatório. Pode ser: C (Caractere) X (Hexadecimal) B (Binário) F (Full-Word) H (Half-Word) E (Full-Word - Ponto Flutuante) D (Double-Word - Ponto Flutuante) L (Duas Double-Words - Ponto Flutuante) P (Compactado)
Compartilhar