Lincoln Arantes Postado Setembro 17, 2019 em 12:38 Compartilhar Postado Setembro 17, 2019 em 12:38 Vamos a pequena e importante dica! Em algumas distribuições Linux já vem instalado o compilador Assembly, como no caso do Fedora 29, bastando apenas o usuário desenvolver seu código e compilar.. Nesse exemplo mando para você um código simples que fiz. Espero que goste! =================================================== .section .data mensagem: .ascii "Lincoln Arantes\n" .section .text .globl _start _start: movq $1, %rax movq $1, %rdi movq $mensagem, %rsi movq $15, %rdx syscall movq $60, %rax movq $0, %rdi syscall ================================================== Desconsidere os sinais de = (igual) Copie o código e salve com o nome hello.s Depois abra o terminal do Linux na pasta onde você salvou o arquivo e compile usando cada linha e teclando [enter] no teclado. # as hello.s -o hello.o # ld -s hello.o -o hello.x Pronto! Para executar digite: ./hello.x Autor: Lincoln César dos Reis Arantes (ADS - graduado) E-mail: lincolnsetelagoas@yahoo.com.br Link para o comentário Compartilhar em outros sites More sharing options...
fredericopissarra Postado Setembro 18, 2019 em 20:17 Compartilhar Postado Setembro 18, 2019 em 20:17 Algumas correções e dicas: # test.S # # $ as -o test.o test.S # $ ld -s -o test test.o # Read Only data section # Usada para conter contantes que nunca serão alteradas. .section .rodata # Label 'mensagem' com a mensagem. # Note que criei o símbolo 'msg_len' que é calculado com o tamanho da mensagem. # O símbolo especial '.' é o equivalente ao $, em outros assemblers. mensagem: .ascii "Lincoln Arantes\n" .equ msg_len, . - mensagem # Code section .section .text # O símbolo _start é usado pelo linker, automaticamente. # pode-se usar outro, mas a opção -e deve ser usada na chamada do linker. .globl _start _start: ; Para criar instruções menores, inicializar registradores de 32 bits ; automaticamente zera os 32 bits superiores dos registradores extendidos. ; Por isso, coloquei 1 em %eax. ; Ainda, copiar %eax para %edi cria uma instrução ainda menor (e zerará os ; 32 bits superiores de %edi). movl $1, %eax movl %eax, %edi ; Usando o endereçamento relativo com RIP gera instruções menores... leaq mensagem(%rip),%rsi ; O símbolo msg_len é usado como constante, daí o $. movl $msg_len, %edx ; Chama a systecall write(). syscall ; Note que zerei %edi via XOR. Usando %edi para aproveitar o zero ; automático dos 32 bits superiores. movl $60, %eax xorl %edi,%edi ; Chama a syscall exit(). syscall Outra coisa... Códigos-fonte em assembly, tipicamente têm extensão .S (maiúsculo)... a extensão .s (minúsculo) geralmente é usado para listagens geradas por outras ferramentas (gcc, por exemplo). []s Fred Link para o comentário Compartilhar em outros sites More sharing options...
fredericopissarra Postado Setembro 18, 2019 em 20:27 Compartilhar Postado Setembro 18, 2019 em 20:27 Observe... seu código (test), depois de compilado com o as, e o meu código (test2), abaixo. Repare que o fato de não usar uma constante calculada para o tamanho da string fez com que você pedisse ao write() para imprimir 1 caracter a menos (o '\n' não irá para stdout!). Repare também que meu código tem 16 bytes a menos... $ objdump -dM intel test | sed -nE '/_start/,$p' 00000000004000b0 <_start>: 4000b0: 48 c7 c0 01 00 00 00 mov rax,0x1 4000b7: 48 c7 c7 01 00 00 00 mov rdi,0x1 4000be: 48 c7 c6 de 00 60 00 mov rsi,0x6000de 4000c5: 48 c7 c2 0f 00 00 00 mov rdx,0xf 4000cc: 0f 05 syscall 4000ce: 48 c7 c0 3c 00 00 00 mov rax,0x3c 4000d5: 48 c7 c7 00 00 00 00 mov rdi,0x0 4000dc: 0f 05 syscall $ objdump -dM intel test2 | sed -nE '/_start/,$p' 00000000004000b0 <_start>: 4000b0: b8 01 00 00 00 mov eax,0x1 4000b5: 89 c7 mov edi,eax 4000b7: 48 8d 35 10 00 20 00 lea rsi,[rip+0x200010] # 6000ce <mensagem> 4000be: ba 10 00 00 00 mov edx,0x10 4000c3: 0f 05 syscall 4000c5: b8 3c 00 00 00 mov eax,0x3c 4000ca: 31 ff xor edi,edi 4000cc: 0f 05 syscall Link para o comentário Compartilhar em outros sites More sharing options...
fredericopissarra Postado Setembro 19, 2019 em 14:23 Compartilhar Postado Setembro 19, 2019 em 14:23 Uma desvantagem de chamar código para processadores Intel de "Assembly" é que existem "Assemblies" diferentes para modos e processadores diferentes. Eis um código que faz a mesma coisa para o ARM (AArch32): @ test.S @ Compilar com: @ as -o test.o test.S @ ld -o test test.o @ Note que tanto faz usar uma instrução ou outra para zerar um registrador: @ mov r1, #0 @ eor r1, r1, r1 @ As instruções do ARM tem tamanho fixo de 32 bits! @ Usando o cortex-a53 como plataforma base! .cpu cortex-a53 .section .rodata msg: .ascii "Hello!\n" .equ msg_len, . - msg .text .globl _start _start: mov r7, #4 @ syscall_write (syscalls ids vão em R7). mov r0, #1 @ fd = STDOUT ldr r1, msgptr @ ptr mov r2, #msg_len @ size swi 0 @ chama a syscall (o vetor 0 é a interface para syscalls!) mov r7, #1 @ syscall_exit mov r1, #0 swi 0 @ chama a syscall. @ No ARM a referência a um símbolo numa outra section @ tem que ser feita de forma indireta?! msgptr: .word msg Dá pra notar que: As instruções e os registradores são completamente diferentes; As systemcalls são diferentes; As regras para acesso a recursos em sections diferentes são... ora bolas... diferentes... "Assembly" é a linguagem mnemônica de programação cujo alvo é um processador de tipo específico, operando em um modo específico. Por exemplo, se você fizer um código para Intel usando instruções como AAA, AAM, DAA, no modo IA-32 (i386), entre outras, elas não poderão ser compiladas para o mesmo processador trabalhando no modo IA-32e (x86-64). Essas instruções não existem no modo x86-64... Escrever programas inteiros diretamente em Assembly (sempre para o processador específico), geralmente, não é uma boa ideia... Link para o comentário Compartilhar em outros sites More sharing options...
fredericopissarra Postado Setembro 26, 2019 em 15:50 Compartilhar Postado Setembro 26, 2019 em 15:50 PS: Note que, no Linux, as syscalls têm, no máximo 7 argumentos... assim o ARM reserva R0-R6 para os argumentos e usa R7 como ID para a syscall, chamando a "interrupção" 0 como interface para as syscalls. Link para o comentário Compartilhar em outros sites More sharing options...
Posts Recomendados
Arquivado
Este tópico foi arquivado e está fechado para novas respostas.