Semáforo em PIC12F629 com programa "errado". Programa de montagem para soma de números

Quando meu filho estava colando um manequim de semáforo em papel para a escola, veio o pensamento: "Por que não montar um modelo funcional de semáforo para ele em um microcontrolador." Na Internet, existem muitos esquemas e programas para eles, implementando o princípio do semáforo mais simples. Mas eles são muito complicados para um brinquedo (conversor DC-DC, registradores de deslocamento, etc.) ou são apresentados apenas como um exemplo do programa mais simples em assembler. Eu quero apresentar um programa esquemático e em linguagem assembly para um semáforo de brinquedo completo com algumas funcionalidades adicionais. Além disso, é montado em um microcontrolador "penny" de acordo com o esquema mais simples, o que é importante para iniciantes. Espero que isso circuito simples se tornará, para muitos iniciantes na programação de microcontroladores PIC, o primeiro projeto real baseado em PIC. Simples, mas ao mesmo tempo contendo as técnicas e atributos básicos da programação, o programa tornará mais fácil entendê-lo e experimentá-lo.

Todo mundo que lida com a programação de microcontroladores conhece os princípios básicos para escrever manipuladores de interrupção: o menor tempo de execução e código possível, sem loops e chamadas do manipulador de outras sub-rotinas, etc. Neste caso, as interrupções são permitidas apenas nas mudanças de nível (não podemos pular outras interrupções, uma vez que simplesmente não existem) e eu, para simplificar o programa e a sua percepção, considerei possível desviar destes princípios. Aqui no manipulador de interrupção há loops e uma chamada para outra sub-rotina e (oh horror!) Até mesmo uma transição para o modo SLEEP. Portanto, no título, o programa é denominado "errado". V este caso, o tratador de interrupção é usado como uma sub-rotina regular; no entanto, em outros casos, os princípios acima, é claro, permanecem válidos.

Breves características do dispositivo:

O dispositivo é um modelo de semáforo com simulação confiável de seu funcionamento (troca de cores, verde piscante) e possui Funções adicionais: alterar a frequência de comutação pressionando um botão, modo amarelo piscando, alternando para o modo de hibernação no manual e modo automático seguido de ligar pressionando um botão. Este dispositivo pode ser usado como um brinquedo infantil, bem como um auxílio visual em instituições pré-escolares para ensinar as crianças a se comportar na estrada.

Portanto, vamos prosseguir para a descrição e consideração do circuito.

O circuito é montado em um microcontrolador PIC12F629 barato. As saídas GP0-GP2, GP4, GP5 (pinos 7, b, 5, 3, 2), programadas como saídas, são utilizadas diretamente para controlar os LEDs. Os LEDs em cada direção são combinados em série para minimizar o consumo de corrente. Os resistores R3-R8 limitam as correntes do LED. No caso de uma grande diferença na saída de LEDs de cores diferentes, você terá que selecionar os resistores apropriados. Para mim, por exemplo, dois grupos amarelos estão ligados em paralelo e ligados a um resistor, aliás, da mesma classificação dos restantes e brilham ainda um pouco mais forte que os outros (o recuo é maior).

Neste circuito, os LEDs são alimentados 1,5 V a mais que o microcontrolador de um elemento adicional (neste caso, quando a saída está desligada, a corrente não passa para a saída do microcircuito, pois é necessária uma tensão muito maior para abrir as transições de dois LEDs (pelo menos 2,5 B). E mesmo com ambos os LEDs perfurados (o que é improvável), a corrente através do diodo de proteção interno para o positivo da fonte de alimentação será de cerca de 7,5 mA, que é muito menor que o corrente permitida. Está experimentalmente estabelecido que, apesar de uma diminuição da corrente pelos LEDs quando a bateria está descarregada, o brilho de seu brilho permanece em um nível aceitável em toda a faixa de tensão da bateria. corrente, o que possibilitou o abandono o interruptor de energia (consumo de corrente no modo de suspensão - 1-3 m kA).

O botão para controlar os modos de operação do dispositivo é conectado ao pino GP3 (pino 4), que é declarado como uma entrada digital nos bits de configuração. Quando o botão é pressionado, ocorre uma interrupção, no manipulador da qual ocorre o seguinte. Quando pressionado por um longo tempo (mais de 4 s), o dispositivo entra no modo de hibernação. Com pressionamentos mais curtos, ocorre uma comutação sequencial da velocidade do semáforo em círculo com a indicação da velocidade atual de acordo com a figura.

No último modo (LEDs vermelhos acesos), o sinal amarelo intermitente é ativado. Com um toque longo no botão (confirmado pela extinção de todos os LEDs), passamos ao funcionamento normal com a mudança do modo para um novo, se o botão não for pressionado por mais de 6 segundos, o modo de operação permanece o mesmo que antes de o botão ser pressionado.

Uma carga de células AA em modo de espera durará pelo menos um ano, razão pela qual o dispositivo não tem um botão liga / desliga. O dispositivo entra em modo de espera também após 0,5 - 1 hora (dependendo da velocidade de troca de cores) sem afetar o botão. O modo SLEEP é encerrado ao pressionar qualquer botão. A energia é fornecida ao microcontrolador através dos pinos 1 e 8. Para salvar os pinos e simplificar o design, o modo do gerador interno sem elementos externos é habilitado.

Pequenas explicações para o programa, que se encontram em anexo.

O processamento de cliques de botão é realizado em sub-rotinas: wait_butt __- espera para pressionar e registro por 6 segundos. sem pressionar, push_butt __- registro da duração do pressionamento, wait_nobutt __- esperando por um botão não pressionado. Quando o estado do semáforo muda (amarelo e verde piscando), os valores da porta de saída são lidos da tabela na sub-rotina tact__ (nibbles baixo ou alto). Da mesma forma, a indicação de status quando o botão é pressionado é da sub-rotina ind__. Para mudar para o modo de espera após o término do tempo de operação, uma transição forçada para a sub-rotina de processamento de interrupção ocorre por instalação de software sinalizador de interrupção. Alterando as constantes CONST_MIN, CONST_REG, CONST_SL, você pode alterar o período de intermitência verde, o modo inicial quando a bateria é conectada, o tempo de operação sem impacto até a transição para o modo SLEEP.

A placa de circuito impresso é feita de fibra de vidro revestida de folha de um lado e tem dimensões de 22x87 mm. Os LEDs externos são instalados paralelamente à placa em diferentes direções. As do meio são instaladas uma na lateral da instalação das peças e a outra na lateral dos trilhos com rosqueamento dos cabos nos orifícios da placa e fixando-as na lateral das peças com uma gota de solda, e do lado das trilhas por soldagem nas trilhas correspondentes.

Todos os resistores com potência de 0,125 W. Os LEDs podem ser adquiridos em qualquer mercado nacional ou importado, de preferência do mesmo tipo com queda de tensão contínua em uma corrente de 10 mA de cerca de 2 Volts. Botão - qualquer um sem fixação. O microcontrolador é instalado no bloco.

A palavra de configuração é inserida na memória automaticamente quando o firmware é carregado (o "birdie" é instalado apenas no item "PWRT", o resto dos itens são "limpos", o "intOSC GP4" é definido no "oscilador" coluna). Primeiramente, é necessário ler o firmware de um microcircuito limpo e escrever o valor da palavra no final da memória do programa no endereço 03FF, que é necessário para ajustar a frequência do gerador interno de uma instância específica do microcircuito. Após carregar o arquivo HEX no programa, este valor deve ser inserido manualmente em 03FF. V este aparelho o desvio de frequência não é crítico, mas você ainda deve estar ciente de que este procedimento é necessário para este microcircuito. Como último recurso, se valor de fábrica perdido, você não pode fazer nada - o programa tomou medidas para a operação correta neste caso.

O dispositivo é colocado em uma caixa de plástico adequada. Os orifícios correspondentes são feitos sob os LEDs na caixa e na tampa. Na minha versão, o próprio semáforo e a base com o botão e a bateria são conectados através de um pedaço de cano d'água de plástico com diâmetro de 20 mm.

O aplicativo contém: modelo, placa de circuito impresso no formato LAY, programa assembler MPASM, arquivo de firmware HEX.

Lista de radioelementos

Designação Tipo de Denominação Quantidade ObservaçãoComprarMeu notebook
IC1 MK PIC 8 bits

PIC12F629

1 MERGULHAR No bloco de notas
R1 Resistor

3 kΩ

1 0,125 W No bloco de notas
R2 Resistor

100 ohm

1 0,125 W No bloco de notas
R3-R8 Resistor

200 ohm

6 0,125 W No bloco de notas
HL1, HL2, HL9, HL10 Diodo emissor de luz

AL307A

4 VERMELHO No bloco de notas
HL3, HL4, HL11, HL12 Diodo emissor de luz

Quando meu filho estava colando um manequim de semáforo em papel para a escola, veio o pensamento: "Por que não montar um modelo funcional de semáforo para ele em um microcontrolador." Na Internet, existem muitos esquemas e programas para eles, implementando o princípio do semáforo mais simples. Mas eles são muito complicados para um brinquedo (conversor DC-DC, registradores de deslocamento, etc.) ou são apresentados apenas como um exemplo do programa mais simples em assembler. Eu quero apresentar um programa esquemático e em linguagem assembly para um semáforo de brinquedo completo com algumas funcionalidades adicionais. Além disso, é montado em um microcontrolador "penny" de acordo com o esquema mais simples, o que é importante para iniciantes. Esperançosamente, este circuito simples se tornará o primeiro projeto real baseado em PIC para muitos que estão começando a aprender programação PIC. Simples, mas ao mesmo tempo contendo as técnicas e atributos básicos da programação, o programa tornará mais fácil entendê-lo e experimentá-lo.

Todo mundo que lida com a programação de microcontroladores conhece os princípios básicos para escrever manipuladores de interrupção: o menor tempo de execução e código possível, sem loops e chamadas do manipulador de outras sub-rotinas, etc. Neste caso, as interrupções são permitidas apenas nas mudanças de nível (não podemos pular outras interrupções, pois simplesmente não existem) e eu, para simplificar o programa e a sua percepção, considerei possível desviar destes princípios. Aqui no manipulador de interrupção há loops e uma chamada para outra sub-rotina e (oh horror!) Até mesmo uma transição para o modo SLEEP. Portanto, no título, o programa é denominado "errado". Nesse caso, o tratador de interrupção é usado como uma sub-rotina normal; no entanto, em outros casos, os princípios acima, é claro, permanecem válidos.

Breves características do dispositivo:

O dispositivo é um modelo de semáforo com simulação confiável do seu funcionamento (troca de cores, verde piscando) e tem funções adicionais: mudar a frequência de chaveamento pressionando um botão, modo amarelo piscando, mudar para modo hibernar em manual e automático modos, seguido de ligar pressionando um botão. Este dispositivo pode ser usado como um brinquedo infantil, bem como um auxílio visual em instituições pré-escolares para ensinar as crianças a se comportar na estrada.

Então, vamos prosseguir para a descrição e consideração do circuito:

O circuito é montado em um microcontrolador barato. As saídas GP0-GP2, GP4, GP5 (pinos 7, b, 5, 3, 2), programadas como saídas, são utilizadas diretamente para controlar os LEDs. Os LEDs em cada direção são combinados em grupos em série, o que minimiza o consumo de corrente. Os resistores R3-R8 limitam as correntes do LED. No caso de uma grande diferença na saída de LEDs de cores diferentes, você terá que selecionar os resistores apropriados. Para mim, por exemplo, dois grupos amarelos são conectados em paralelo e conectados a um resistor, e têm o mesmo valor que o resto e brilham ainda mais forte que os outros (o recuo é maior).

Neste circuito, 1,5 V é fornecido aos LEDs a mais do que ao microcontrolador por um elemento adicional (neste caso, quando a saída está desligada, a corrente não passa para a saída do microcircuito, pois é necessária uma tensão muito maior para abrir as transições de dois LEDs (pelo menos 2,5 B). E mesmo com ambos os LEDs perfurados (o que é improvável), a corrente através do diodo de proteção interno para o positivo da fonte de alimentação será de cerca de 7,5 mA, que é muito menos do que a corrente permitida. É experimentalmente estabelecido que, apesar de uma diminuição da corrente através dos LEDs quando a bateria está descarregada, o brilho de seu brilho permanece em um nível aceitável em toda a faixa de tensão da bateria. corrente, o que tornou isso possível abandonar o interruptor de energia (consumo de corrente no modo de hibernação - 1-3 m kA).

O botão para controlar os modos de operação do dispositivo é conectado ao pino GP3 (pino 4), que é declarado como uma entrada digital nos bits de configuração. Quando o botão é pressionado, ocorre uma interrupção, no manipulador da qual ocorre o seguinte. Quando pressionado por um longo tempo (mais de 4 s), o dispositivo entra no modo de hibernação. Com pressionamentos mais curtos, há uma comutação sequencial da velocidade do semáforo em círculo com a indicação da velocidade atual conforme a figura:

No último modo (LEDs vermelhos acesos), o sinal amarelo intermitente é ativado. Com um toque longo no botão (confirmado pela extinção de todos os LEDs), passamos ao funcionamento normal com a mudança do modo para um novo, se o botão não for pressionado por mais de 6 segundos, o modo de operação permanece o mesmo que antes de o botão ser pressionado.

Uma carga de células AA em modo de espera durará pelo menos um ano, razão pela qual o dispositivo não tem um botão liga / desliga. O dispositivo entra em modo de espera também após 0,5 - 1 hora (dependendo da velocidade de troca de cores) sem afetar o botão. O modo SLEEP é encerrado ao pressionar qualquer botão. A energia é fornecida ao microcontrolador através dos pinos 1 e 8. Para salvar os pinos e simplificar o design, o modo do gerador interno sem elementos externos é habilitado.

Pequenas explicações para o programa, que se encontram em anexo:

O processamento de cliques de botão é realizado em sub-rotinas: wait_butt __- espera para pressionar e registrar por 6 segundos. sem pressionar, push_butt __- registro da duração do pressionamento, wait_nobutt __- esperando por um botão não pressionado. Quando o estado do semáforo muda (amarelo e verde piscando), os valores da porta de saída são lidos da tabela na sub-rotina tact__ (nibbles baixo ou alto). Da mesma forma, a indicação de status quando o botão é pressionado é da sub-rotina ind__. Para mudar para o modo de hibernação após o término do tempo de operação, uma transição forçada para a rotina de processamento de interrupção ocorre pela configuração do software do sinalizador de interrupção. Alterando as constantes CONST_MIN, CONST_REG, CONST_SL, você pode alterar o período de intermitência verde, o modo inicial quando a bateria é conectada, o tempo de operação sem impacto até a transição para o modo SLEEP.

A placa de circuito impresso é feita de fibra de vidro revestida em folha de um lado e tem dimensões de 22x87 mm. Os LEDs externos são instalados paralelamente à placa em diferentes direções. As do meio são instaladas uma na lateral da instalação das peças e a outra na lateral dos trilhos com rosqueamento dos cabos nos orifícios da placa e fixando-as na lateral das peças com uma gota de solda, e do lado das trilhas por soldagem nas trilhas correspondentes.

Todos os resistores são 0,125W. Os LEDs podem ser adquiridos em qualquer mercado nacional ou importado, de preferência do mesmo tipo com queda de tensão contínua em uma corrente de 10 mA de cerca de 2 Volts. Botão - qualquer um sem fixação. O microcontrolador é instalado no bloco.

A palavra de configuração é inserida na memória automaticamente quando o firmware é carregado (no IC-Prog, o "birdie" é instalado apenas no item "PWRT", o resto dos itens são "limpos", "intOSC GP4" é definido em coluna “oscilador”). Primeiro, é necessário ler o firmware de um microcircuito limpo e escrever o valor da palavra no final da memória do programa no endereço 03FF, que é necessário para ajustar a frequência do gerador interno de uma determinada instância de microcircuito. Após carregar o arquivo HEX no programa, este valor deve ser inserido manualmente em 03FF. Neste dispositivo, o desvio de frequência não é crítico, mas você ainda deve estar ciente de que este procedimento é necessário para este microcircuito. Como último recurso, se o valor de fábrica for perdido, você não pode fazer nada - o programa tomou medidas para o funcionamento correto neste caso.

O dispositivo é colocado em uma caixa de plástico adequada. Os orifícios correspondentes são feitos sob os LEDs na caixa e na tampa. Na minha versão, o próprio semáforo e a base com o botão e a bateria são conectados através de um pedaço de cano d'água de plástico com diâmetro de 20 mm.

Olá!
Eu quero mostrar como um programa é escrito para controlar equipamentos tecnológicos em um PLC.
Na maior parte do tempo, lidei com um CLP fabricado pela Schneider Electric. O Quantum que escolhi para esta tarefa é o PLC mais poderoso e caro deste fabricante. Pode controlar equipamentos com milhares de sinais, para semáforos em Vida real naturalmente, ninguém vai usá-lo.

Eu nunca lidei com automação de semáforos, então eu mesmo criei o algoritmo. Aqui está:
1. Semáforo para passagem de pedestres regulamentada. Aqueles. semáforo para automóveis, semáforo para peões e um botão para peões, ao premir o mesmo, o peão avisa que pretende atravessar a via.
2. Após o início do programa, acendem-se luzes verdes para automóveis e vermelhas para peões.
3. Depois que o pedestre pressiona o botão, pisca o verde para carros, depois o amarelo e depois o vermelho. Depois disso, acende-se o sinal verde para pedestres, após definir tempo ele começa a piscar, fica vermelho para pedestres, depois para carros fica amarelo e vermelho, depois verde.
4. Durante um período de tempo especificado após um semáforo verde em um semáforo de pedestres, pressionar o botão por um pedestre não inicia o algoritmo de travessia. Nesse caso, o algoritmo de transição inicia somente após o tempo especificado ter decorrido.
A programação do PLC é realizada no ambiente de programação Unity nas linguagens da norma IEC 61131-3. V este padrão inclui 5 idiomas. Por exemplo, escolhi a linguagem dos blocos de função - FBD.
Aqui está o navegador do projeto no Unity:

Configurando o PLC:


O PLC consiste em um painel de montagem, uma fonte de alimentação (1), um controlador (2), um módulo de entrada digital para 32 sinais de 24 Vcc (4), um módulo de entrada digital para 32 sinais de 24 Vcc (5). Em um projeto real de painéis de montagem conectados a um controlador por várias redes, pode haver dezenas e há centenas de módulos de E / S.
Criamos variáveis ​​dos tipos necessários no editor de variáveis:


As variáveis ​​associadas aos canais dos módulos de E / S possuem um endereço que indica a qual rack, módulo e canal o sinal está vinculado.
O programa consiste em seções que são executadas a cada ciclo da varredura do controlador em ordem.
O ciclo de varredura do controlador simplificado tem a seguinte aparência:
1. Leitura de sinais de entrada do módulo de entrada em variáveis ​​com endereços.
2. Execução de seções.
3. Escrevendo valores de variáveis ​​com endereços para os sinais de saída dos módulos de saída.
4. Vá para o item 1.
Crie uma seção de relógio com um gerador de pulso de 0,5 segundo. O bloco TP, quando o sinal de entrada muda de 0 para 1, emite um pulso de uma determinada duração.


Aqui e abaixo, as capturas de tela das seções são mostradas no modo de animação, não no modo de edição. Eles exibem os valores das variáveis ​​em este momento tempo ao conectar a um PLC com um programa carregado (números para variáveis ​​numéricas, verde (1) -vermelho (0) para booleano).
A seção principal trata da lógica principal.
O bloco SR define a saída para 1 quando S1 = 1 e redefine a saída para 0 quando R = 1.
O bloco R_TRIG define a saída de 1 ciclo de varredura para 1 quando a entrada faz a transição de 0 para 1 (detector de borda de ataque).
O bloco F_TRIG define a saída de 1 ciclo de varredura para 1 quando a entrada faz a transição de 1 para 0 (detector de borda de fuga).
A variável inButton associada ao canal do botão foi substituída na seção por inButtonForTest para que você possa alterar seu valor no simulador do controlador sem hardware real.


A seção de saídas gera sinais de saída para controlar semáforos.


Carregue o projeto no simulador de controlador:


O significado de qualquer variável pode ser visto na tabela de animação:


Mas, para a conveniência da depuração, você pode fazer uma tela do operador com gráficos simples, cuja animação está ligada a variáveis:

Tentando atravessar a estrada:

Não esperava que fossem necessários 30 blocos para controlar um objeto tão simples como um semáforo.
No próximo artigo vou mostrar como escrever este programa usando todos os idiomas do padrão IEC 61131-3 simultaneamente.

UPD. Corrigido um erro no nome do padrão.

(Formas), (Painel).

Antes de criar um aplicativo, você deve estudar a descrição dos novos componentes.

Exercício. Simule semáforos. Ao iniciar o projeto, o painel do semáforo deve estar vazio. Depois de pressionar o botão Iniciar, os semáforos começam a mudar. Após pressionar o botão Parar, o painel do semáforo fica vazio novamente. Usando um cronômetro, verifique se o sinal de trânsito muda em intervalos regulares. No campo Velocidade, insira o intervalo do cronômetro.

Progresso do projeto

1. Crie novo projeto... Salve-o em uma pasta separada com o nome Traffic Light.

2. Coloque no formulário um painel (TPanel) com três formas (TShape), dois botões (TButton), um campo de texto (TEdit), uma inscrição (TLabel), um cronômetro (TTimer) de acordo com a amostra:

Deve ser assim:

2. Nós fazemos o design:

Defina estes valores de propriedade no inspetor de objetos:

Componente Propriedade Significado
Formulário 1 Rubrica Luzes de trânsito
Panel1 Rubrica * Vazio *
Forma1 Forma StCircle
Forma2 Forma StCircle
Shape3 Forma StCircle
Label1 Rubrica Velocidade
Edit1 Texto * vazio *
Button1 Rubrica Começar
Button2 Rubrica Pare

3. Crie um evento para Form1 na seção OnCreate - Pressione as reticências

Crie um evento para Timer1 na seção OnTimer - pressione reticências

4. Atribua cores às formas:

Tipo final de trabalho:

5. Durante o carregamento do formulário, o cronômetro desliga, as formas no painel tornam-se invisíveis.

Crie um manipulador de eventos para o evento FormCreate (clique duas vezes no componente Form1) e cole este código:

var k: inteiro; procedimento TForm1.FormCreate (Sender: TObject); começar Timer1.Enabled: = false; Forma1.Visível: = falso; Forma2.Visível: = falso; Forma3.Visível: = falso; fim;

6. Para trocar as lâmpadas do semáforo, escreva o código do programa no manipulador de eventos Timer1Timer. Este código será executado com o intervalo que o usuário inserir no campo Velocidade. De acordo com as leituras do temporizador, é determinado o número da lâmpada, que deve acender em este momento.

Clique duas vezes no componente Timer1 e cole este código:

6. Escreva o código do programa para o botão Iniciar. Ao clicar no botão do campo Velocidade, o intervalo do cronômetro é lido, o cronômetro é zerado e o cronômetro é ligado.

Clique duas vezes no componente Button1 e cole o código:

procedimento TForm1.Button1Click (Sender: TObject); começar Timer1.Interval: = StrToInt (Edit1.text); k: = 0; Timer1.Enabled: = true; fim;

7. Escreva o código para o botão Parar. Após clicar no botão, o cronômetro deve desligar, os semáforos ficam invisíveis novamente.

Clique duas vezes no componente Button2 e cole o código:

procedimento TForm1.Button2Click (Sender: TObject); começar Timer1.Enabled: = false; Forma1.Visível: = falso; Forma2.Visível: = falso; Forma3.Visível: = falso; fim;

8. Inicie o projeto. No campo Velocidade, insira 1000 (1000ms = 1s). Os semáforos começarão a alternar em intervalos de um segundo.

Artem Poznyak, aluno de 10 turmas "A" da escola secundária №23, Ekibasbuz

Muitas pessoas pensam que o Assembler já está desatualizado e não é usado em nenhum lugar, mas principalmente esses são jovens que não estão profissionalmente envolvidos na programação de sistemas. O desenvolvimento de software, é claro, é bom, mas ao contrário das linguagens de programação de alto nível, Assembler irá ensiná-lo a entender profundamente o funcionamento de um computador, otimizar o trabalho com recursos de hardware e também programar qualquer técnica, desenvolvendo assim na direção do aprendizado de máquina . Para entender este antigo YP, primeiro você precisa praticar com programas simples que melhor explica a funcionalidade do Assembler.

IDE para Assembler

A primeira pergunta é: em qual ambiente de desenvolvimento devo programar em Assembler? A resposta é inequívoca - MASM32... isto programa padrão, que é usado para este PL. Você pode baixá-lo no site oficial masm32.com na forma de um arquivo, que precisará ser descompactado e, em seguida, executar o instalador install.exe. Como alternativa, você pode usar FASM, mas o código para ele será significativamente diferente.

Antes de iniciar o trabalho, o principal é não se esquecer de adicionar a seguinte linha à variável de sistema PATH:

C: \ masm32 \ bin

Programa de montagem "Hello World"

Acredita-se que este programa básico em programação, que os iniciantes escrevem primeiro quando se familiarizam com a linguagem. Talvez essa abordagem não seja totalmente correta, mas de uma forma ou de outra permite que você veja imediatamente um resultado visual:

386 .model flat, opção stdcall casemap: none include /masm32/include/windows.inc include /masm32/include/user32.inc include /masm32/include/kernel32.inc includelib /masm32/lib/user32.lib includelib / masm32 / lib / kernel32.lib .data msg_title db "Título", 0 msg_message db "Hello world", 0 .code start: invocar MessageBox, 0, addr msg_message, addr msg_title, MB_OK invocar ExitProcess, 0 end start

Primeiro, execute o editor qeditor.exe na pasta com MASM32 instalado e escreva o código do programa nele. Depois disso, nós o salvamos como um arquivo com a extensão ".asm" e construímos o programa usando o item de menu "Projeto" → "Construir tudo". Se não houver erros no código, o programa será compilado com sucesso, e na saída obteremos um arquivo exe pronto que mostrará windows windows com a inscrição "Olá, mundo".

Adicionando dois números no assembler

Nesse caso, procuramos ver se a soma dos números é zero ou não. Se for o caso, uma mensagem correspondente aparecerá na tela e, caso contrário, outra notificação será exibida.

486 .model flat, opção stdcall casemap: none include /masm32/include/windows.inc include /masm32/include/user32.inc include /masm32/include/kernel32.inc includelib /masm32/lib/user32.lib includelib / masm32 / lib / kernel32.lib include /masm32/macros/macros.asm uselib masm32, comctl32, ws2_32 .data .code start: mov eax, 123 mov ebx, -90 add eax, ebx test eax, eax jz zero invocar MessageBox, 0, chr $ ("In eax não 0!"), chr $ ("Info"), 0 jmp lexit zero: invoke MessageBox, 0, chr $ ("In eax 0!"), chr $ ("Info"), 0 lexit: invocar ExitProcess, 0 end start

Aqui usamos os chamados rótulos e times especiais usando-os (jz, jmp, teste). Vamos olhar mais de perto:

  • teste - usado para comparação lógica de variáveis ​​(operandos) na forma de bytes, palavras ou palavras duplas. Para comparação, o comando usa multiplicação lógica e olha os bits: se eles forem iguais a 1, então o bit de resultado será igual a 1, caso contrário - 0. Se obtivermos 0, os sinalizadores são definidos junto com ZF (sinalizador zero ), que será igual a 1 Os resultados são então analisados ​​com base no ZF.
  • jnz - se o sinalizador ZF não foi definido em nenhum lugar, um salto é executado neste rótulo. Este comando é freqüentemente usado quando o programa contém operações de comparação que de alguma forma afetam o resultado ZF. Isso inclui teste e cmp.
  • jz - se o sinalizador ZF ainda estiver definido, o rótulo é saltado.
  • jmp - independentemente de haver ZF ou não, o rótulo é saltado.

Programa de montagem para soma de números

Um programa primitivo que mostra o processo de adição de duas variáveis:

486 .model flat, opção stdcall casemap: none include /masm32/include/windows.inc include /masm32/include/user32.inc include /masm32/include/kernel32.inc includelib /masm32/lib/user32.lib includelib / masm32 / lib / kernel32.lib include /masm32/macros/macros.asm uselib masm32, comctl32, ws2_32 .data msg_title db "Title", 0 A DB 1h B DB 2h buffer db 128 dup (?) formato db "% d", 0 .code start: MOV AL, A ADD AL, B invoca wsprintf, addr buffer, addr format, eax invoca MessageBox, 0, addr buffer, addr msg_title, MB_OK invoca ExitProcess, 0 end start

No Assembler, para calcular a soma, serão necessárias várias ações, pois a linguagem de programação trabalha diretamente com a memória do sistema. Aqui, manipulamos principalmente recursos e, independentemente, indicamos quanto alocar para uma variável, de que forma perceber os números e onde colocá-los.

Obtendo um valor da linha de comando no assembler

Uma das etapas básicas mais importantes na programação é obter dados do console para processamento posterior. Neste caso, nós os obtemos de linha de comando e exibir na janela do Windows:

486 .model flat, opção stdcall casemap: none include /masm32/include/windows.inc include /masm32/include/user32.inc include /masm32/include/kernel32.inc includelib /masm32/lib/user32.lib includelib / masm32 / lib / kernel32.lib include /masm32/macros/macros.asm uselib masm32, comctl32, ws2_32 .data .code start: call GetCommandLine; o resultado será colocado em eax push 0 push chr $ ("Linha de Comando") push eax; pegamos o texto para a saída de eax push 0 chamada MessageBox push 0 chamada ExitProcess end start

Você também pode usar um método alternativo:

486 .model flat, opção stdcall casemap: none include /masm32/include/windows.inc include /masm32/include/user32.inc include /masm32/include/kernel32.inc includelib /masm32/lib/user32.lib includelib / masm32 / lib / kernel32.lib include /masm32/macros/macros.asm uselib masm32, comctl32, ws2_32 .data .code start: call GetCommandLine; o resultado será colocado em eax invocar GetCommandLine invocar MessageBox, 0, eax, chr $ ("Command Line"), 0 invocar ExitProcess, 0 push 0 chamar ExitProcess end start

Ele usa invoke, uma macro especial que simplifica o código do programa. No momento da compilação, os comandos de macro são convertidos em comandos do montador. De uma forma ou de outra, usamos uma pilha - uma forma primitiva de armazenar dados, mas ao mesmo tempo muito conveniente. Por convenção stdcall, em todas as funções WinAPI, as variáveis ​​são passadas pela pilha, apenas em ordem reversa, e são colocados no registro correspondente eax.

Loops de montador

Caso de uso:

Dados msg_title db "Título", 0 A DB 1h buffer db 128 dup (?) Formato db "% d", 0 .code start: mov AL, A .REPEAT inc AL .UNTIL AL == 7 invocar wsprintf, addr buffer, addr format, AL invocar MessageBox, 0, addr buffer, addr msg_title, MB_OK invocar ExitProcess, 0 end start .data msg_title db "Title", 0 buffer db 128 dup (?) format db "% d", 0 .code start: mov eax, 1 mov edx, 1 .WHILE edx == 1 inc eax .IF eax == 7 .BREAK .ENDIF .ENDW invocar wsprintf, addr buffer, addr format, eax invoke MessageBox, 0, addr buffer, addr msg_title, MB_OK invocar ExitProcess, 0

O comando repeat é usado para criar um loop. Então, usando inc, o valor da variável é aumentado em 1, independentemente de estar em memória de acesso aleatório, ou no próprio processador. Para interromper o trabalho do ciclo, utiliza-se a diretiva ".BREAK". Ele pode interromper o ciclo e continuar sua ação após a "pausa". Você também pode interromper a execução do código do programa e verificar a condição repeat e while usando a diretiva ".CONTINUE".

Soma dos elementos da matriz no montador

Aqui, resumimos os valores das variáveis ​​na matriz usando um loop for:

486 .model flat, stdcall option casemap: none include /masm32/include/windows.inc include /masm32/include/user32.inc include /masm32/include/kernel32.inc includelib /masm32/lib/user32.lib includelib / masm32 / lib / kernel32.lib include /masm32/macros/macros.asm uselib masm32, comctl32, ws2_32 .data msg_title db "Title", 0 A DB 1h x dd 0,1,2,3,4,5,6,7, 8,9,10,11 n dd 12 buffer db 128 dup (?) Formato db "% d", 0 .code start: mov eax, 0 mov ecx, n mov ebx, 0 L: add eax, x add ebx, tipo x dec ecx cmp ecx, 0 jne L invocar wsprintf, addr buffer, formato addr, eax invocar MessageBox, 0, addr buffer, addr msg_title, MB_OK invocar ExitProcess, 0 end start

O comando dec, como inc, altera o valor do operando em um, apenas na direção oposta, em -1. Mas cmp compara variáveis ​​pelo método de subtração: ele subtrai um valor do segundo e, dependendo do resultado, define os sinalizadores apropriados.

O comando jne navega pelo rótulo com base no resultado da comparação de variáveis. Se for negativo, ocorre uma transição, e se os operandos não forem iguais, a transição não é realizada.

O montador é interessante por sua representação de variáveis, o que permite que você faça o que quiser com elas. Um especialista que descobriu todas as complexidades desta linguagem programação, possui um conhecimento realmente valioso que pode ser usado de muitas maneiras. Um problema pode ser resolvido pela maioria jeitos diferentes, então o caminho será espinhoso, mas não menos emocionante.

Visualizações da postagem: 767