11
Arquitetura de Computadores
UFPB
11
Arquitetura de Computadores
UFPB
22
Arquitetura de Computadores
UNIPE
7
Arquitetura de Computadores
UNIP
1
Arquitetura de Computadores
UERJ
57
Arquitetura de Computadores
UERJ
2
Arquitetura de Computadores
UERJ
1
Arquitetura de Computadores
UERJ
1
Arquitetura de Computadores
PUC
2
Arquitetura de Computadores
PUC
Texto de pré-visualização
UNIVERSIDADE FEDERAL DA PARAÍBA CENTRO DE INFORMÁTICA DISCIPLINA Arquitetura de Computadores PROFESSOR Ewerton Monteiro Salvador TRABALHO COM LINGUAGEM ASSEMBLY Redução de volume de áudio O programa especificado abaixo deverá ser implementado utilizandose a linguagem Assembly no Windows MASM 32 bits ou no Linux NASM 32 bits O trabalho será em trios e deverá ser enviado pelo SIGAA até as 2359h do dia 20102024 ESPECIFICAÇÃO Escreva um programa que solicite 3 entradas o nome de um arquivo de entrada o nome de um arquivo de saída e uma constante de redução de volume entre 1 e 10 Os nomes dos arquivos devem ter até 50 caracteres e não precisam incluir o caminho completo ou seja considere que os arquivos estarão no mesmo diretório do programa executável Os nomes dos arquivos informados irão se referir a arquivos de áudio de extensão WAV com um único canal e um único componente de áudio chunk Após receber as entradas o programa deverá copiar os bytes do cabeçalho do arquivo de entrada no arquivo de saída e em seguida deverá dividir cada conjunto de 2 bytes tipo WORD após o cabeçalho pela constante de redução de volume informada pelo usuário escrevendo o resultado dessa divisão inteira no arquivo de saída Após o fechamento do arquivo de saída deve ser perguntado ao usuário se oa mesmoa gostaria de reduzir o volume de outro arquivo de áudio Figura 1 Na parte de cima se encontra representado um arquivo de áudio de entrada e na parte de baixo se encontra representado um arquivo de saída com cada amostra do áudio dividida por uma constante de redução Observações importantes Os grupos não devem se preocupar em validar as entradas de dados Assumam que o usuário sempre digitará valores válidos como entradas de dados Tanto no Windows quanto no Linux deverão ser utilizadas as chamadas oficiais do sistema operacional para abrir ler escrever e fechar arquivos não sendo permitido o uso de outras bibliotecas para esse fim O processo de leitura e escrita de arquivos após a cópia do cabeçalho deve utilizar buffers de 16 bytes Ou seja utilize um buffer de 16 bytes para ler as amostrar de áudio e um buffer de 16 bytes armazenar o resultado dessas amostras dividido pela constante de redução de volume O programa deve implementar pelo menos uma função para reduzir o volume de um buffer de leitura do arquivo 16 bytes Essas funções devem receber três parâmetros na seguinte ordem 1 o endereço do buffer de entrada ou seja passar o buffer de entrada por referência 2 o endereço do buffer de saída e 3 a constante de redução de volume um inteiro de 1 a 10 do tipo WORD 2 bytes16 bits A função não deve retornar nenhum valor A não utilização de função acarretará em redução da nota do trabalho Não é permitida a utilização de pseudoinstruções Assembly além daquelas utilizadas na disciplina até o momento por exemplo invoke do MASM32 Se você possui dúvida se pode ou não utilizar um determinado recurso do MASM ou do NASM por favor consulte o professor da disciplina A entrada e saída de console no Windows deve utilizar as funções ReadConsole e WriteConsole da biblioteca kernel32 A utilização da macro printf no MASM32 acarretará em redução da nota do trabalho No Linux podem ser utilizadas as funções printf e scanf da biblioteca padrão da linguagem C utilizando o gcc para linkagem do programa Cada grupo deverá tomar medidas para garantir que o códigofonte possua boa legibilidade comentários são cruciais nesse sentido e que o programa seja minimamente eficiente ou seja o programa não deverá realizar ações claramente desnecessárias para a solução do problema A implementação deve ser feita em Assembly versão 32 bits para Windows MASM32 ou em 32 bits para Linux NASM O trabalho deve ser desenvolvido em trio O código implementado deve ser original não sendo permitidas cópias de códigos inteiros ou trechos de códigos de outras fontes exceto quando expressamente autorizado pelo professor da disciplina Por esse motivo recomenda se enfaticamente que não haja compartilhamento de código entre os alunos da disciplina Também fica proibido o upload de código em repositórios públicos na Internet ou seja se a equipe for fazer o upload de um código para um serviço como o GitHub o repositório precisará ser configurado para ser de acesso privado Os debates entre alunos devem estar restritos a ideias e estratégias e nunca envolver códigos para evitar penalidades na nota relacionadas à plágio Também não é permitido o uso de código gerado por sistemas de inteligência artificial generativa como o ChatGPT o qual deverá ser utilizado apenas para tirar possíveis dúvidas dos alunos e não para gerar o código que de fato irá para o trabalho a ser desenvolvido Boa sorte SUGESTÃO DE ROTEIRO DE DESENVOLVIMENTO DO PROJETO Lembrese de testar cada um desses passos antes de progredir para o passo seguinte Passo Pontuação Máxima Esperada 1 Escreva um programa executável em Assembly 32bits que não faz nada 05 2 Faça com que o programa escreva na tela as mensagens de solicitações de entrada 10 3 Receba as entradas de dados doa usuárioa 20 4 Teste a sua habilidade de abrir os arquivos de entrada e de saída e em seguida leia apenas os 44 primeiros bytes do cabeçalho do arquivo de entrada e escreva esses 44 bytes no arquivo de saída fechando ambos os arquivos ao final do processo Abra o arquivo de saída para confirmar que a cópia foi bem sucedida 30 5 Agora implemente um loop que seja capaz de ler o arquivo de entrada inteiro de 16 em 16 bytes escrevendo o conteúdo ainda inalterado no arquivo de saída também de 16 em 16 bytes Abra o arquivo de saída para confirmar que a cópia foi bem sucedida 50 6 Implemente o processamento das amostras de áudio de 2 bytes no buffer de 16 bytes onde cada amostra de áudio é dividida pela constante de redução de volume e escrita no buffer de saída para ser gravado no arquivo de saída 70 7 Transforme a implementação do processamento do buffer Passo 6 em uma função conforme a especificação do projeto 90 8 Certifiquese que o seu código esteja tão legível quanto possível organizado e comentado 100 INFOMAÇÕES COMPLEMENTARES PARA O PROJETO Considerando Windows 32 bits e Linux 32 bits Como lidar com arquivos Tanto no Windows como no Linux o tratamento de arquivos é similar sendo essencialmente o mesmo utilizado em linguagens de programação de alto nível como C Solicitase ao sistema operacional a abertura de um arquivo em modo de leitura de escrita ou ambos O sistema operacional devolve um handle que serve como um número de identificação do arquivo aberto para ser utilizado nas chamadas de sistemas seguintes que envolvam esse arquivo O sistema operacional define um apontador de arquivo para todos os arquivos abertos o qual é controlado automaticamente pelo próprio sistema operacional A abertura de um arquivo tipicamente faz com que esse apontador seja posicionado na primeira posição posição 0 primeiro byte desse arquivo e é incrementado sempre que uma leitura ou uma escrita é realizada Existe uma função do sistema operacional que permite que oa programadora reposicione esse apontador de arquivo contudo essa função não será necessário para este projeto Leituras e escritas são realizadas através de chamadas de sistemas operacionais próprias A leitura ou escrita sempre começa na posição atual do apontador de arquivo controlado pelo sistema operacional O apontador de arquivo é incrementado ao final de uma operação de leitura ou escrita de acordo com a quantidade de bytes envolvida nessa operação Por fim arquivos devem ser fechados através de uma chamada ao sistema operacional O fechamento do arquivo garante que dados escrito sejam corretamente gravados além de liberar recursos do sistema operacional que foram alocados para o tratamento do arquivo No Windows 32 bits as chamadas de sistema relacionadas a arquivos se encontram na biblioteca kernel32 com constantes definidas no arquivo de cabeçalho windowsinc No Linux 32 bits as chamadas de sistema relacionadas a arquivos são invocadas através da interrupção 80h CriaçãoAbertura de Arquivo Windows Realizada através da função CreateFile Parâmetros 1 Apontador endereço de string contendo o nome do arquivo a ser aberto no nosso projeto o nome não precisa incluir o caminho de diretórios considerando que o arquivo estará no mesmo diretório do arquivo executável do projeto Observação importante strings recebidas através de funções de entrada de dados como ReadConsole do MASM32 costumam ser terminadas com os caracteres ASCII Carriage Return CR decimal 13 seguido de Line Feed LF decimal 10 seguido finalmente do terminador de string decimal 0 Contudo um nome de arquivo não deve conter os caracteres CR ou LF portanto a string recebida por esse tipo de função precisa ser tratada para remover esses caracteres problemáticos O trecho de código abaixo trecho de código autorizado para ser utilizado no projeto percorre uma string procurando o caractere CR ASCII 13 e quando encontra esse caractere o substitui pelo valor 0 terminador de string Dessa forma a string resultante desse tratamento pode ser utilizada na função para abertura de arquivo mov esi offset umastring Armazenar apontador da string em esi proximo mov al esi Mover caractere atual para al inc esi Apontar para o proximo caractere cmp al 13 Verificar se eh o caractere ASCII CR FINALIZAR jne proximo dec esi Apontar para caractere anterior xor al al ASCII 0 mov esi al Inserir ASCII 0 no lugar do ASCII CR 2 Constante de 4 bytes informando o nível de acesso desejado para o arquivo Exemplos dessas constantes são GENERICREAD e GENERICWRITE as quais devem ser utilizadas nesse projeto para operações de escrita ou leitura Uma operação de escrita e leitura pode ser alcançada através de uma operação OR entre as constantes GENERICREAD e GENERICWRITE contudo esse tipo de operação de leitura e escrita em um mesmo arquivo não será necessária neste projeto 3 Constante de 4 bytes informando se o acesso ao arquivo será compartilhado ou não Exemplos dessas constantes são 0 zero FILESHAREWRITE FILESHAREREAD etc Como o arquivo desse projeto não precisará de acesso compartilhado com outros programas essa constante deverá ser definida como 0 zero 4 Apontador para uma estrutura do tipo SECURITYATRIBUTES definida em windowsinc contendo atributos de segurança Esse parâmetro não será necessário nesse projeto ou seja deverá ser informada aqui a constante NULL 5 Constante de 4 bytes especificando a necessidade de se criar ou não um novo arquivo Exemplos dessas constantes são CREATEALWAYS CREATENEW OPENALWAYS OPENEXISTING etc Neste projeto deverá ser utilizada a opção OPENEXISTING para abertura do arquivo de entrada e CREATEALWAYS para a criação do arquivo de saída de modo que o arquivo original só seja aberto e nunca criado e o arquivo de destino seja sempre um novo arquivo 6 Constante de 4 bytes especificando os atributos do arquivo a ser aberto como FILEATTRIBUTEARCHIVE FILEATTRIBUTENORMAL etc Como este projeto não utilizará atributos especiais deverá ser utilizada a opção FILEATTRIBUTENORMAL 7 Um handle de 4 bytes para um arquivo que sirva de template quanto a atributos Como este projeto não utilizará atributos especiais deverá ser utilizada a constante NULL Retorno um handle para o arquivo é retornado através do registrador EAX Ex invoke CreateFile addr fileName GENERICREAD 0 NULL OPENEXISTING FILEATTRIBUTENORMAL NULL mov fileHandle eax Criação com abertura de Arquivo Linux Realizada através da interrupção 80h Parâmetros 1 O registrador EAX deve receber o valor 8 referente à chamada de sistema syscreat 2 O registrador EBX deve conter um apontador endereço de string contendo o nome do arquivo a ser aberto no nosso projeto o nome não precisa incluir o caminho de diretórios considerando que o arquivo estará no mesmo diretório do arquivo executável do projeto 3 O registrador ECX deve conter as permissões do arquivo de acordo com a convenção de permissões de arquivos utilizada pelo Linux essa convenção utiliza números na base octal Por exemplo a permissão 777 dá acesso total a arquivos leitura escrita e execução para o usuário dono do arquivo para o grupo do dono e para todos os usuários do sistema Retorno um handle para o arquivo é retornado através do registrador EAX Um retorno 1 indica a ocorrência de erro Ex mov eax 8 syscreat mov ebx filename mov ecx 0o777 int 80h mov fileHandle eax Abertura de Arquivo Já Existente Linux Realizada através da interrupção 80h Parâmetros 1 O registrador EAX deve receber o valor 5 referente à chamada de sistema sysopen 2 O registrador EBX deve conter um apontador endereço de string contendo o nome do arquivo a ser aberto no nosso projeto o nome não precisa incluir o caminho de diretórios considerando que o arquivo estará no mesmo diretório do arquivo executável do projeto 3 O registrador ECX deve conter o modo de acesso do arquivo Os mais comuns são 0 readonly 1 writeonly e 2 readwrite 4 O registrador EDX deve conter as permissões do arquivo de acordo com a convenção de permissões de arquivos utilizada pelo Linux essa convenção utiliza números na base octal Por exemplo a permissão 777 dá acesso total a arquivos leitura escrita e execução para o usuário dono do arquivo para o grupo do dono e para todos os usuários do sistema Retorno um handle para o arquivo é retornado através do registrador EAX Um retorno 1 indica a ocorrência de erro Ex mov eax 5 sysopen mov ebx filename mov ecx 0 readonly mov edx 0o777 int 80h mov fileHandle eax Leitura de Arquivo Windows Realizada através da função ReadFile Parâmetros 1 Handle de 4 bytes do arquivo a ser lido Esse handle é recebido como retorno da função de abertura do arquivo 2 Um apontador para um array de bytes onde serão gravados os bytes lidos do arquivo 3 Um inteiro de 4 bytes indicando a quantidade de bytes máxima a ser lida do arquivo Observe que essa quantidade máxima de bytes deve ser igual ou inferior à quantidade de bytes do array de bytes utilizado para gravação dos dados 4 Apontador para um inteiro de 4 bytes onde será gravado a quantidade de bytes efetivamente lidos do arquivo Importante quando a leitura chegar ao final do arquivo a quantidade de bytes lida será 0 e isso será o indicativo de que você chegou no fim do arquivo 5 Apontador para estrutura OVERLAPPED utilizada para acessos assíncronos ao arquivo Como neste projeto utilizaremos acessos síncronos por simplicidade esse parâmetro deve conter a constante NULL Retorno 0 se a leitura falhar e um número diferente de zero se for bemsucedida Ex invoke ReadFile fileHandle addr fileBuffer 10 addr readCount NULL Le 10 bytes do arquivo Leitura de Arquivo Linux Realizada através da interrupção 80h Parâmetros 1 O registrador EAX deve receber o valor 3 referente à chamada de sistema sysread 2 O registrador EBX deve conter o handle do arquivo Esse handle é recebido como retorno da função de aberturacriação do arquivo 3 O registrador ECX deve conter um apontador para um array de bytes onde serão gravados os bytes lidos do arquivo 4 O registrador EDX deve conter um inteiro indicando a quantidade de bytes máxima a ser lida do arquivo Observe que essa quantidade máxima de bytes deve ser igual ou inferior à quantidade de bytes do array de bytes utilizado para gravação dos dados Retorno No registrador EAX terá a quantidade de bytes efetivamente lidos do arquivo Retorno 1 indica a ocorrência de erro Importante quando a leitura chegar ao final do arquivo a quantidade de bytes lida será 0 e isso será o indicativo de que você chegou no fim do arquivo Ex mov eax 3 sysread mov ebx fileHandle mov ecx fileBuffer mov edx 10 int 80h Escrita de Arquivo Windows Realizada através da função WriteFile Parâmetros 1 Handle de 4 bytes do arquivo a ser escrito Esse handle é recebido como retorno da função de abertura do arquivo 2 Um apontador para um array de bytes a serem gravados no arquivo 3 Um inteiro de 4 bytes indicando a quantidade de bytes a ser gravada Observe que essa quantidade máxima de bytes deve ser igual ou inferior à quantidade de bytes do array de bytes utilizado para gravação dos dados 4 Apontador para um inteiro de 4 bytes onde será gravado a quantidade de bytes efetivamente escritos no arquivo 5 Apontador para estrutura OVERLAPPED utilizada para acessos assíncronos ao arquivo Como neste projeto utilizaremos acessos síncronos por simplicidade esse parâmetro deve conter a constante NULL Retorno 0 se a escrita falhar e um número diferente de zero se for bemsucedida Um retorno 1 indica a ocorrência de erro Ex invoke WriteFile fileHandle addr fileBuffer 10 addr writeCount NULL Escreve 10 bytes do arquivo Escrita de Arquivo Linux Realizada através da interrupção 80h Parâmetros 1 O registrador EAX deve receber o valor 4 referente à chamada de sistema syswrite 2 O registrador EBX deve conter o handle do arquivo Esse handle é recebido como retorno da função de aberturacriação do arquivo 3 O registrador ECX deve conter um apontador para um array de bytes com o conteúdo a ser gravado no arquivo 4 O registrador EDX deve conter um inteiro indicando a quantidade de bytes máxima a ser escrita no arquivo Retorno No registrador EAX terá a quantidade de bytes efetivamente escritos no arquivo Um retorno 1 indica a ocorrência de erro Ex mov eax 4 syswrite mov ebx fileHandle mov ecx fileBuffer mov edx 10 int 80h Fechamento de Arquivo Windows Realizada através da função CloseHandle Parâmetros 1 Handle de 4 bytes do arquivo a ser fechado Esse handle é recebido como retorno da função de abertura do arquivo Retorno 0 se o fechamento falhar e um número diferente de zero se for bemsucedido Ex invoke CloseHandle fileHandle Fechamento de Arquivo Linux Realizada através da interrupção 80h Parâmetros 2 O registrador EAX deve receber o valor 6 referente à chamada de sistema sysclose 3 O registrador EBX deve conter o handle do arquivo Esse handle é recebido como retorno da função de aberturacriação do arquivo Retorno No registrador EAX terá um código em caso de erro Um retorno 1 indica a ocorrência de erro Ex mov eax 6 sysclose mov ebx fileHandle int 80h Verificando códigos de erro Windows Realizado através da função GetLastError Retorno um código de erro de 4 bytes de acordo com as listagens disponíveis no seguinte link httpslearnmicrosoftcomenuswindowswin32debugsystemerrorcodes Ex invoke GetLastError Qual é o formato do arquivo WAV Um arquivo WAV se inicia com um cabeçalho formado por 44 bytes bytes 0 a 43 conforme a ilustração abaixo Fonte httpsoundfilesapporgdocWaveFormat Em seguida os dados de amostras de áudio codificação PCM de 2 bytes cada 16 bits são disponibilizados a partir do byte 44 seção data da imagem acima As amostras de áudio são números inteiros com sinal ou seja os números podem ser negativos Dessa forma a divisão deve ser feita com a instrução idiv a qual possui a mesma estrutura da instrução div ou seja a instrução recebe um único operando que é o divisor a ser utilizado O dividendo deverá estar armazenado nos registradores DXAX Como no contexto desse projeto todos os dividendos terão 16 bits o registrador DX deve ser inicializado com 16 bits 0 ou 16 bits 1 dependendo do número em AX ser positivo ou negativo Esse processo de inicialização do registrador DX com o número de sinal correto pode ser feita utilizando a instrução cwd a qual não utiliza nenhum operando mas que só deve ser utilizada quando AX possuir um número válido Ex cwd idiv bx
11
Arquitetura de Computadores
UFPB
11
Arquitetura de Computadores
UFPB
22
Arquitetura de Computadores
UNIPE
7
Arquitetura de Computadores
UNIP
1
Arquitetura de Computadores
UERJ
57
Arquitetura de Computadores
UERJ
2
Arquitetura de Computadores
UERJ
1
Arquitetura de Computadores
UERJ
1
Arquitetura de Computadores
PUC
2
Arquitetura de Computadores
PUC
Texto de pré-visualização
UNIVERSIDADE FEDERAL DA PARAÍBA CENTRO DE INFORMÁTICA DISCIPLINA Arquitetura de Computadores PROFESSOR Ewerton Monteiro Salvador TRABALHO COM LINGUAGEM ASSEMBLY Redução de volume de áudio O programa especificado abaixo deverá ser implementado utilizandose a linguagem Assembly no Windows MASM 32 bits ou no Linux NASM 32 bits O trabalho será em trios e deverá ser enviado pelo SIGAA até as 2359h do dia 20102024 ESPECIFICAÇÃO Escreva um programa que solicite 3 entradas o nome de um arquivo de entrada o nome de um arquivo de saída e uma constante de redução de volume entre 1 e 10 Os nomes dos arquivos devem ter até 50 caracteres e não precisam incluir o caminho completo ou seja considere que os arquivos estarão no mesmo diretório do programa executável Os nomes dos arquivos informados irão se referir a arquivos de áudio de extensão WAV com um único canal e um único componente de áudio chunk Após receber as entradas o programa deverá copiar os bytes do cabeçalho do arquivo de entrada no arquivo de saída e em seguida deverá dividir cada conjunto de 2 bytes tipo WORD após o cabeçalho pela constante de redução de volume informada pelo usuário escrevendo o resultado dessa divisão inteira no arquivo de saída Após o fechamento do arquivo de saída deve ser perguntado ao usuário se oa mesmoa gostaria de reduzir o volume de outro arquivo de áudio Figura 1 Na parte de cima se encontra representado um arquivo de áudio de entrada e na parte de baixo se encontra representado um arquivo de saída com cada amostra do áudio dividida por uma constante de redução Observações importantes Os grupos não devem se preocupar em validar as entradas de dados Assumam que o usuário sempre digitará valores válidos como entradas de dados Tanto no Windows quanto no Linux deverão ser utilizadas as chamadas oficiais do sistema operacional para abrir ler escrever e fechar arquivos não sendo permitido o uso de outras bibliotecas para esse fim O processo de leitura e escrita de arquivos após a cópia do cabeçalho deve utilizar buffers de 16 bytes Ou seja utilize um buffer de 16 bytes para ler as amostrar de áudio e um buffer de 16 bytes armazenar o resultado dessas amostras dividido pela constante de redução de volume O programa deve implementar pelo menos uma função para reduzir o volume de um buffer de leitura do arquivo 16 bytes Essas funções devem receber três parâmetros na seguinte ordem 1 o endereço do buffer de entrada ou seja passar o buffer de entrada por referência 2 o endereço do buffer de saída e 3 a constante de redução de volume um inteiro de 1 a 10 do tipo WORD 2 bytes16 bits A função não deve retornar nenhum valor A não utilização de função acarretará em redução da nota do trabalho Não é permitida a utilização de pseudoinstruções Assembly além daquelas utilizadas na disciplina até o momento por exemplo invoke do MASM32 Se você possui dúvida se pode ou não utilizar um determinado recurso do MASM ou do NASM por favor consulte o professor da disciplina A entrada e saída de console no Windows deve utilizar as funções ReadConsole e WriteConsole da biblioteca kernel32 A utilização da macro printf no MASM32 acarretará em redução da nota do trabalho No Linux podem ser utilizadas as funções printf e scanf da biblioteca padrão da linguagem C utilizando o gcc para linkagem do programa Cada grupo deverá tomar medidas para garantir que o códigofonte possua boa legibilidade comentários são cruciais nesse sentido e que o programa seja minimamente eficiente ou seja o programa não deverá realizar ações claramente desnecessárias para a solução do problema A implementação deve ser feita em Assembly versão 32 bits para Windows MASM32 ou em 32 bits para Linux NASM O trabalho deve ser desenvolvido em trio O código implementado deve ser original não sendo permitidas cópias de códigos inteiros ou trechos de códigos de outras fontes exceto quando expressamente autorizado pelo professor da disciplina Por esse motivo recomenda se enfaticamente que não haja compartilhamento de código entre os alunos da disciplina Também fica proibido o upload de código em repositórios públicos na Internet ou seja se a equipe for fazer o upload de um código para um serviço como o GitHub o repositório precisará ser configurado para ser de acesso privado Os debates entre alunos devem estar restritos a ideias e estratégias e nunca envolver códigos para evitar penalidades na nota relacionadas à plágio Também não é permitido o uso de código gerado por sistemas de inteligência artificial generativa como o ChatGPT o qual deverá ser utilizado apenas para tirar possíveis dúvidas dos alunos e não para gerar o código que de fato irá para o trabalho a ser desenvolvido Boa sorte SUGESTÃO DE ROTEIRO DE DESENVOLVIMENTO DO PROJETO Lembrese de testar cada um desses passos antes de progredir para o passo seguinte Passo Pontuação Máxima Esperada 1 Escreva um programa executável em Assembly 32bits que não faz nada 05 2 Faça com que o programa escreva na tela as mensagens de solicitações de entrada 10 3 Receba as entradas de dados doa usuárioa 20 4 Teste a sua habilidade de abrir os arquivos de entrada e de saída e em seguida leia apenas os 44 primeiros bytes do cabeçalho do arquivo de entrada e escreva esses 44 bytes no arquivo de saída fechando ambos os arquivos ao final do processo Abra o arquivo de saída para confirmar que a cópia foi bem sucedida 30 5 Agora implemente um loop que seja capaz de ler o arquivo de entrada inteiro de 16 em 16 bytes escrevendo o conteúdo ainda inalterado no arquivo de saída também de 16 em 16 bytes Abra o arquivo de saída para confirmar que a cópia foi bem sucedida 50 6 Implemente o processamento das amostras de áudio de 2 bytes no buffer de 16 bytes onde cada amostra de áudio é dividida pela constante de redução de volume e escrita no buffer de saída para ser gravado no arquivo de saída 70 7 Transforme a implementação do processamento do buffer Passo 6 em uma função conforme a especificação do projeto 90 8 Certifiquese que o seu código esteja tão legível quanto possível organizado e comentado 100 INFOMAÇÕES COMPLEMENTARES PARA O PROJETO Considerando Windows 32 bits e Linux 32 bits Como lidar com arquivos Tanto no Windows como no Linux o tratamento de arquivos é similar sendo essencialmente o mesmo utilizado em linguagens de programação de alto nível como C Solicitase ao sistema operacional a abertura de um arquivo em modo de leitura de escrita ou ambos O sistema operacional devolve um handle que serve como um número de identificação do arquivo aberto para ser utilizado nas chamadas de sistemas seguintes que envolvam esse arquivo O sistema operacional define um apontador de arquivo para todos os arquivos abertos o qual é controlado automaticamente pelo próprio sistema operacional A abertura de um arquivo tipicamente faz com que esse apontador seja posicionado na primeira posição posição 0 primeiro byte desse arquivo e é incrementado sempre que uma leitura ou uma escrita é realizada Existe uma função do sistema operacional que permite que oa programadora reposicione esse apontador de arquivo contudo essa função não será necessário para este projeto Leituras e escritas são realizadas através de chamadas de sistemas operacionais próprias A leitura ou escrita sempre começa na posição atual do apontador de arquivo controlado pelo sistema operacional O apontador de arquivo é incrementado ao final de uma operação de leitura ou escrita de acordo com a quantidade de bytes envolvida nessa operação Por fim arquivos devem ser fechados através de uma chamada ao sistema operacional O fechamento do arquivo garante que dados escrito sejam corretamente gravados além de liberar recursos do sistema operacional que foram alocados para o tratamento do arquivo No Windows 32 bits as chamadas de sistema relacionadas a arquivos se encontram na biblioteca kernel32 com constantes definidas no arquivo de cabeçalho windowsinc No Linux 32 bits as chamadas de sistema relacionadas a arquivos são invocadas através da interrupção 80h CriaçãoAbertura de Arquivo Windows Realizada através da função CreateFile Parâmetros 1 Apontador endereço de string contendo o nome do arquivo a ser aberto no nosso projeto o nome não precisa incluir o caminho de diretórios considerando que o arquivo estará no mesmo diretório do arquivo executável do projeto Observação importante strings recebidas através de funções de entrada de dados como ReadConsole do MASM32 costumam ser terminadas com os caracteres ASCII Carriage Return CR decimal 13 seguido de Line Feed LF decimal 10 seguido finalmente do terminador de string decimal 0 Contudo um nome de arquivo não deve conter os caracteres CR ou LF portanto a string recebida por esse tipo de função precisa ser tratada para remover esses caracteres problemáticos O trecho de código abaixo trecho de código autorizado para ser utilizado no projeto percorre uma string procurando o caractere CR ASCII 13 e quando encontra esse caractere o substitui pelo valor 0 terminador de string Dessa forma a string resultante desse tratamento pode ser utilizada na função para abertura de arquivo mov esi offset umastring Armazenar apontador da string em esi proximo mov al esi Mover caractere atual para al inc esi Apontar para o proximo caractere cmp al 13 Verificar se eh o caractere ASCII CR FINALIZAR jne proximo dec esi Apontar para caractere anterior xor al al ASCII 0 mov esi al Inserir ASCII 0 no lugar do ASCII CR 2 Constante de 4 bytes informando o nível de acesso desejado para o arquivo Exemplos dessas constantes são GENERICREAD e GENERICWRITE as quais devem ser utilizadas nesse projeto para operações de escrita ou leitura Uma operação de escrita e leitura pode ser alcançada através de uma operação OR entre as constantes GENERICREAD e GENERICWRITE contudo esse tipo de operação de leitura e escrita em um mesmo arquivo não será necessária neste projeto 3 Constante de 4 bytes informando se o acesso ao arquivo será compartilhado ou não Exemplos dessas constantes são 0 zero FILESHAREWRITE FILESHAREREAD etc Como o arquivo desse projeto não precisará de acesso compartilhado com outros programas essa constante deverá ser definida como 0 zero 4 Apontador para uma estrutura do tipo SECURITYATRIBUTES definida em windowsinc contendo atributos de segurança Esse parâmetro não será necessário nesse projeto ou seja deverá ser informada aqui a constante NULL 5 Constante de 4 bytes especificando a necessidade de se criar ou não um novo arquivo Exemplos dessas constantes são CREATEALWAYS CREATENEW OPENALWAYS OPENEXISTING etc Neste projeto deverá ser utilizada a opção OPENEXISTING para abertura do arquivo de entrada e CREATEALWAYS para a criação do arquivo de saída de modo que o arquivo original só seja aberto e nunca criado e o arquivo de destino seja sempre um novo arquivo 6 Constante de 4 bytes especificando os atributos do arquivo a ser aberto como FILEATTRIBUTEARCHIVE FILEATTRIBUTENORMAL etc Como este projeto não utilizará atributos especiais deverá ser utilizada a opção FILEATTRIBUTENORMAL 7 Um handle de 4 bytes para um arquivo que sirva de template quanto a atributos Como este projeto não utilizará atributos especiais deverá ser utilizada a constante NULL Retorno um handle para o arquivo é retornado através do registrador EAX Ex invoke CreateFile addr fileName GENERICREAD 0 NULL OPENEXISTING FILEATTRIBUTENORMAL NULL mov fileHandle eax Criação com abertura de Arquivo Linux Realizada através da interrupção 80h Parâmetros 1 O registrador EAX deve receber o valor 8 referente à chamada de sistema syscreat 2 O registrador EBX deve conter um apontador endereço de string contendo o nome do arquivo a ser aberto no nosso projeto o nome não precisa incluir o caminho de diretórios considerando que o arquivo estará no mesmo diretório do arquivo executável do projeto 3 O registrador ECX deve conter as permissões do arquivo de acordo com a convenção de permissões de arquivos utilizada pelo Linux essa convenção utiliza números na base octal Por exemplo a permissão 777 dá acesso total a arquivos leitura escrita e execução para o usuário dono do arquivo para o grupo do dono e para todos os usuários do sistema Retorno um handle para o arquivo é retornado através do registrador EAX Um retorno 1 indica a ocorrência de erro Ex mov eax 8 syscreat mov ebx filename mov ecx 0o777 int 80h mov fileHandle eax Abertura de Arquivo Já Existente Linux Realizada através da interrupção 80h Parâmetros 1 O registrador EAX deve receber o valor 5 referente à chamada de sistema sysopen 2 O registrador EBX deve conter um apontador endereço de string contendo o nome do arquivo a ser aberto no nosso projeto o nome não precisa incluir o caminho de diretórios considerando que o arquivo estará no mesmo diretório do arquivo executável do projeto 3 O registrador ECX deve conter o modo de acesso do arquivo Os mais comuns são 0 readonly 1 writeonly e 2 readwrite 4 O registrador EDX deve conter as permissões do arquivo de acordo com a convenção de permissões de arquivos utilizada pelo Linux essa convenção utiliza números na base octal Por exemplo a permissão 777 dá acesso total a arquivos leitura escrita e execução para o usuário dono do arquivo para o grupo do dono e para todos os usuários do sistema Retorno um handle para o arquivo é retornado através do registrador EAX Um retorno 1 indica a ocorrência de erro Ex mov eax 5 sysopen mov ebx filename mov ecx 0 readonly mov edx 0o777 int 80h mov fileHandle eax Leitura de Arquivo Windows Realizada através da função ReadFile Parâmetros 1 Handle de 4 bytes do arquivo a ser lido Esse handle é recebido como retorno da função de abertura do arquivo 2 Um apontador para um array de bytes onde serão gravados os bytes lidos do arquivo 3 Um inteiro de 4 bytes indicando a quantidade de bytes máxima a ser lida do arquivo Observe que essa quantidade máxima de bytes deve ser igual ou inferior à quantidade de bytes do array de bytes utilizado para gravação dos dados 4 Apontador para um inteiro de 4 bytes onde será gravado a quantidade de bytes efetivamente lidos do arquivo Importante quando a leitura chegar ao final do arquivo a quantidade de bytes lida será 0 e isso será o indicativo de que você chegou no fim do arquivo 5 Apontador para estrutura OVERLAPPED utilizada para acessos assíncronos ao arquivo Como neste projeto utilizaremos acessos síncronos por simplicidade esse parâmetro deve conter a constante NULL Retorno 0 se a leitura falhar e um número diferente de zero se for bemsucedida Ex invoke ReadFile fileHandle addr fileBuffer 10 addr readCount NULL Le 10 bytes do arquivo Leitura de Arquivo Linux Realizada através da interrupção 80h Parâmetros 1 O registrador EAX deve receber o valor 3 referente à chamada de sistema sysread 2 O registrador EBX deve conter o handle do arquivo Esse handle é recebido como retorno da função de aberturacriação do arquivo 3 O registrador ECX deve conter um apontador para um array de bytes onde serão gravados os bytes lidos do arquivo 4 O registrador EDX deve conter um inteiro indicando a quantidade de bytes máxima a ser lida do arquivo Observe que essa quantidade máxima de bytes deve ser igual ou inferior à quantidade de bytes do array de bytes utilizado para gravação dos dados Retorno No registrador EAX terá a quantidade de bytes efetivamente lidos do arquivo Retorno 1 indica a ocorrência de erro Importante quando a leitura chegar ao final do arquivo a quantidade de bytes lida será 0 e isso será o indicativo de que você chegou no fim do arquivo Ex mov eax 3 sysread mov ebx fileHandle mov ecx fileBuffer mov edx 10 int 80h Escrita de Arquivo Windows Realizada através da função WriteFile Parâmetros 1 Handle de 4 bytes do arquivo a ser escrito Esse handle é recebido como retorno da função de abertura do arquivo 2 Um apontador para um array de bytes a serem gravados no arquivo 3 Um inteiro de 4 bytes indicando a quantidade de bytes a ser gravada Observe que essa quantidade máxima de bytes deve ser igual ou inferior à quantidade de bytes do array de bytes utilizado para gravação dos dados 4 Apontador para um inteiro de 4 bytes onde será gravado a quantidade de bytes efetivamente escritos no arquivo 5 Apontador para estrutura OVERLAPPED utilizada para acessos assíncronos ao arquivo Como neste projeto utilizaremos acessos síncronos por simplicidade esse parâmetro deve conter a constante NULL Retorno 0 se a escrita falhar e um número diferente de zero se for bemsucedida Um retorno 1 indica a ocorrência de erro Ex invoke WriteFile fileHandle addr fileBuffer 10 addr writeCount NULL Escreve 10 bytes do arquivo Escrita de Arquivo Linux Realizada através da interrupção 80h Parâmetros 1 O registrador EAX deve receber o valor 4 referente à chamada de sistema syswrite 2 O registrador EBX deve conter o handle do arquivo Esse handle é recebido como retorno da função de aberturacriação do arquivo 3 O registrador ECX deve conter um apontador para um array de bytes com o conteúdo a ser gravado no arquivo 4 O registrador EDX deve conter um inteiro indicando a quantidade de bytes máxima a ser escrita no arquivo Retorno No registrador EAX terá a quantidade de bytes efetivamente escritos no arquivo Um retorno 1 indica a ocorrência de erro Ex mov eax 4 syswrite mov ebx fileHandle mov ecx fileBuffer mov edx 10 int 80h Fechamento de Arquivo Windows Realizada através da função CloseHandle Parâmetros 1 Handle de 4 bytes do arquivo a ser fechado Esse handle é recebido como retorno da função de abertura do arquivo Retorno 0 se o fechamento falhar e um número diferente de zero se for bemsucedido Ex invoke CloseHandle fileHandle Fechamento de Arquivo Linux Realizada através da interrupção 80h Parâmetros 2 O registrador EAX deve receber o valor 6 referente à chamada de sistema sysclose 3 O registrador EBX deve conter o handle do arquivo Esse handle é recebido como retorno da função de aberturacriação do arquivo Retorno No registrador EAX terá um código em caso de erro Um retorno 1 indica a ocorrência de erro Ex mov eax 6 sysclose mov ebx fileHandle int 80h Verificando códigos de erro Windows Realizado através da função GetLastError Retorno um código de erro de 4 bytes de acordo com as listagens disponíveis no seguinte link httpslearnmicrosoftcomenuswindowswin32debugsystemerrorcodes Ex invoke GetLastError Qual é o formato do arquivo WAV Um arquivo WAV se inicia com um cabeçalho formado por 44 bytes bytes 0 a 43 conforme a ilustração abaixo Fonte httpsoundfilesapporgdocWaveFormat Em seguida os dados de amostras de áudio codificação PCM de 2 bytes cada 16 bits são disponibilizados a partir do byte 44 seção data da imagem acima As amostras de áudio são números inteiros com sinal ou seja os números podem ser negativos Dessa forma a divisão deve ser feita com a instrução idiv a qual possui a mesma estrutura da instrução div ou seja a instrução recebe um único operando que é o divisor a ser utilizado O dividendo deverá estar armazenado nos registradores DXAX Como no contexto desse projeto todos os dividendos terão 16 bits o registrador DX deve ser inicializado com 16 bits 0 ou 16 bits 1 dependendo do número em AX ser positivo ou negativo Esse processo de inicialização do registrador DX com o número de sinal correto pode ser feita utilizando a instrução cwd a qual não utiliza nenhum operando mas que só deve ser utilizada quando AX possuir um número válido Ex cwd idiv bx