Jump to content

fredericopissarra

Membros
  • Content Count

    173
  • Joined

  • Last visited

Everything posted by fredericopissarra

  1. # ip link eth0 set macaddr xx:xx:xx:xx:xx:xx Se o device aceitar... Obtenha a lista de devices com: # ip link
  2. Acredito que a área "Programação" seja adequada. Basta apenas o povo postar suas dúvidas por lá...
  3. Eis um problema simples que surgiu num forum que sigo... O sujeito queria um jeito de obter o campo do expoente de um double sem usar operadores aritméticos, lógicos, "address-of" e indireção, ou seja, os operadores +, -, *, /, %, &, |, ^ ou ~. Se isso fosse permitido, a solução seria tão simples como: #include <stdint.h> /* Estrutura de um 'double' */ struct double_s { uint64_t f:52; unsigned int e:11; unisgned int s:1; }; int getext( double x ) { struct double_s *p = (struct double_s *)&x; return p->e - 1023; }; Existe uma solução simples, usando uma função da libm, basta a chamada para frexp(). Mas, existe também uma solução matemática. Se você quer descobrir um expoente, use logaritmo: Ou seja: int getext( double x ) { return floor(log2(fabs(x))); } A razão do floor é que o expoente de uma estrutura em ponto flutuante marca o início da janela onde a fração se encontra. Para valores menores que 1 o logaritmo lhe dará valores negativos e precisamos do maior valor menor que x. Já que x pode ser negativo (e não estamos interessados no sinal), obter o seu valor absoluto impede de usarmos valores inválidos para o logaritmo. Ambas as soluções com frexp e log2, são lentas (embora frexp seja a mais rápida delas). De qualquer maneira, é um problema trivial... 😉
  4. Acho pouco provável a existência de computadores quânticos nos próximos 25 anos...
  5. Nos idos do início do século XX acreditavam que teríamos carros voadores... 🙂
  6. Sei... MSBuild e PowerShell agora viraram "código aberto"... tá... ok... Aliás... MSBuild, MS Word e PowerShell... código aberto... a-hã! Tá...
  7. No caso, se alguém acha os manuais da Intel "complicados" de consultar e até mesmo contraditórios em alguns pontos. Os manuais da AMD costumam ser melhores: https://developer.amd.com/resources/developer-guides-manuals/
  8. Pois é... isso meio que detona o "aprendizado com foco nas exigências de mercado", não é? Por que tem tanta gente interessada nessas áreas se a "oportunidade de emprego" é tão baixa? A motivação pode ser o sonho de tornar-se um especialista numa área complexa o suficiente para não haver muita competição... o que é louvável... Mas para tanto, a coisa exige MUITO estudo e sem uma tutela padronizada (aulas fomais, diplomas, títulos), ou seja, o sujeito tende a aprender porque gosta da coisa e quer se destacar. Minha opinião (é claro, só pode ser minha! senão não seria opinião!) é que os "caçadores de emprego" tendem a não aprender coisa alguma, ou não o suficiente para fazer qualquer diferença profissional... Existe uma legião de mediocridade "no mercado" e isso é, justamente, o que eles esperam (pouca oferta [de emprego] para grande demanda [de empregados em potencial]) levam a baixas remunerações e carga de trabalho exasperantes. Veja só as exigências de competência dos candidatos. O sujeito só não precisa saber como construir uma máquina de teletransporte usando chiclete, clip de papel e cuspe...
  9. Hummm... ok, então isso ajuda: Ralf Brown Interrupt List
  10. O problema de usar NASM (ou outro assembler) para criar executáveis é que grande parte das bibliotecas padrão e dos compiladores C geram código bem mais otimizado... É uma questão de trocar o tamanho pela performance e vice-versa.
  11. UNIX Network Programming - The Socket Networking API (W. Richard Stevens)
  12. PS; É claro... se quiser adicionar elementos no final da lista: void addtail( list_T *lstp, void *elemp ) { node_T *p = elemp; // esse será o último elemento! p->next = NULL; if ( ! lstp->tail ) // lista vazia? { lstp->head = lstp->tail = p; return; } // ajusta o nó tail atual para o novo nó. lstp->tail->next = p; lstp->tail = p; }
  13. A turma da OOP acredita que lidar com coisas como polimorfismo é impossível em linguagens "estruturadas". Eis um exemplo de como fazer uma lista de encadeamento simples, em C, com elementos de diversos "tipos"... Considere a palavra-reservada struct: Ela existe para juntar vários tipos em um único container e de forma ordenada. Assim, se definirmos um nó genérico como: typedef struct node_s { struct node_s *next; } node_T; // _T porque _t não deve ser usado! Podemos definir uma estrutura de controle para uma lista como: // Usado para inicializar uma estrutura de lista vazia. #define EMPTY_LIST { NULL, NULL } typedef struct list_s { node_T *head, *tail; } list_T; Podemos agora usar a regra de que todo elemento que será colocado nessa lista deve definir, primeiro, um ponteiro do tipo node_T que aponte para o próximo item da lista... Por exemplo, suponha que eu queira criar uma lista de vetores 3D (x,y,z). Posso definir os elementos como: struct vec3d_element_s { node_T *next; // isso TEM que estar aqui! // nosso vetor: double x, y, z; }; Eis uma rotina que adiciona elementos no início de uma lista: // note que elemp é ponteiro para void, aceita qualquer ponteiro! void addhead( list_T *lstp, void *elemp ) { node_T *p = elemp; p->next = lstp->head; lstp->head = p; // o elemento é a nova 'cabeça' da lista. // Se a lista estiver previamente vazia, temos um novo 'rabo'. if ( ! lstp->tail ) lstp->tail = p; } Note que, junto com a definição da estrutura de lista, defini um macro EMPTY_LIST. Isso permite o seguinte uso: // define uma lista vazia. list_T list = EMPTY_LIST; struct vec3d_element_s *elemp; // ponteiro para nosso novo elemento. elemp = malloc( sizeof *elemp ); // aloca elemento. elemp->x = 0.0; // inicializa dados do elemento. elemp->y = 1.0; elemp->z = sqrt(2.0); // adiciona elemento na lista: addhead( &list, elemp ); Note que nossa lista aceita QUALQUER estrutura que tenha, como seu primeiro membro, um ponteiro para node_T nomeado de next. Poderíamos fazer algo assim: enum vec_type { V2D, V3D, V4D }; struct vec_element_s { node_T *next; enum vec_type vtype; double v[0]; // yep... tamanho 0! }; ... list_T list = EMPTY_LIST; ... // Aloca vetor 2D, inicializa-o e coloca na lista: struct vec_element_s *v2d; v2d = malloc( sizeof *v2d + 2*sizeof( double ) ); v2d->vtype = V2D; v2d->v[0] = 1.0; v2d->v[1] = 2.0; addhead( &list, v2d ); // Aloca vetor 3D, inicializa-o e coloca na lista. struct vec_element_s *v3d; v3d = malloc( sizeof *v3d + 3*sizeof( double ) ); v3d->vtype = V3D; v3d->v[0] = 1.0; v3d->v[1] = 2.0; v3d->v[1] = 3.0; addhead( &list, v2d ); // percorre a lista e faz algo com os elementos: node_T *p; p = list.head; while ( p ) { doSomething( p ); p = p->next; } Na hora de percorrer a lista podemos usar o membro vtype para dedicir o tamanho do array v. Mas, note que a lista não se importa com o tipo do elemento, desde que ele tenha o ponteiro next como primeiro item.
  14. Costumam manter essa página atualizada: https://en.wikipedia.org/wiki/Public_recursive_name_server
  15. Um aviso: nameservers retornam a resposta em pacotes TCP se essa for maior que um determinado tamanho (ajustado no bind). A requisição da consulta pode e deve ser feita por UDP, mas a resposta pode ser UDP ou TCP, dependendo do tamanho... Exemplo: O google retorna resposta em UDP para consultas de até 512 bytes: $ dig @8.8.8.8 www.google.com ; <<>> DiG 9.11.3-1ubuntu1.7-Ubuntu <<>> @8.8.8.8 www.google.com ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10492 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 512 ;; QUESTION SECTION: ;www.google.com. IN A ;; ANSWER SECTION: www.google.com. 129 IN A 172.217.29.36 ;; Query time: 42 msec ;; SERVER: 8.8.8.8#53(8.8.8.8) ;; WHEN: Mon May 20 22:36:39 -03 2019 ;; MSG SIZE rcvd: 59 Note o comentário EDNS, acima... Já o cloudflare retorna em UDP pacotes com até 1452 bytes: $ dig @1.0.0.1 www.google.com ; <<>> DiG 9.11.3-1ubuntu1.7-Ubuntu <<>> @1.0.0.1 www.google.com ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36721 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 1452 ;; QUESTION SECTION: ;www.google.com. IN A ;; ANSWER SECTION: www.google.com. 41 IN A 216.58.202.164 ;; Query time: 38 msec ;; SERVER: 1.0.0.1#53(1.0.0.1) ;; WHEN: Mon May 20 22:38:46 -03 2019 ;; MSG SIZE rcvd: 59 O "default" do bind é 4096 bytes. Quando o nameserver recursivo retorna respostas tão grandes? Quando existem muitos nomes associados à resposta! Um exemplo é o google.com, se pedirmos qualquer registro: $ dig +noall +answer www.google.com any www.google.com. 288 IN AAAA 2800:3f0:4001:814::2004 www.google.com. 161 IN A 172.217.29.228 Aqui só tem 2, mas poderiam ter vários registros A, vários AAAA, vários CNAMEs, ... consultas que também retornam a autoridade, e adicionais.
  16. Não quer gastar mais dinheiro que o necessário (pizza é cara, hoje em dia!)? Quer comer a maior quantidade de pizza possível? Preste atenção nisso: https://bitismyth.wordpress.com/2017/09/25/o-problema-das-pizzas-ou-o-problema-da-ignorancia-da-matematica-elementar/
  17. Um artiguinho meu (e o follow up mostrando como montei o gráfico animado) - escritos em Agosto de 2017: https://bitismyth.wordpress.com/2017/08/23/estatisticamente-insignificante/ https://bitismyth.wordpress.com/2017/08/25/o-grafico-animado-dos-sorteios-howto/
  18. Meu conselho: Faça um curso de alguma área que te agrade, no qual você pretenda dedicar uma vida de estudos, com prazer... No que toca o "mercado de trabalho", sempre existem oportunidades para quem tem curso superior (seja lá em que área for)... Eu, por exemplo, tenho dois colegas com formação superior em biologia e são, hoje, analistas de sistemas! Conheço gente até com curso de culinária que se encaixa nesse perfil. Se você escolher um "curso", onde você vai dedicar uns bons 4 ou 5 anos para terminar (se não tomar "pau" no meio do caminho) somente por critérios "profissionais", acredite, pode se arrepender muito.
  19. Apenas um detalhe... O header PE não começa, necessariamente, no offset 0x80. Isso depende do tamanho do DOS Stub. A especificação do PE diz, claramente, que é necessário ler o offset do header PE no offset 0x3C do arquivo. Além disso, enquanto uma demonstração simples possa usar, sem problemas, streaming. Como a manipulação é binária, seria interessante evitar buffering e usar file descriptors ao invés do tipo FILE. Eis um exemplo do código inicial modificado (que checa qualquer possibilidade de erros, no caso de tentar usá-lo com um arquivo que não tem formato PE): // test.c // Compila apenas no Visual Studio ou GCC para Windows (MinGW, CygWin). #if defined(_MSC_VER) || defined(__WINNT__) # include <io.h> /* Windows não tem basename()! */ # define basename(...) (__VA_ARGS__) #else # ifdef __GNUC__ /* Esse bloco é para outro systema que não seja Windows ou MinGW */ # define _GNU_SOURCE # include <unistd.h> # include <string.h> # else # error Need MSVC, MinGW, Cygwin or GCC to compile! # endif #endif #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <fcntl.h> #include <ctype.h> static void show_buffer ( void *, size_t ); int main ( int argc, char **argv ) { int fd; uint32_t pe_pos; char buffer[4]; if ( argc != 2 ) { fprintf ( stderr, "Uso: %s <exefile>\n", basename ( *argv ) ); return EXIT_FAILURE; } // abrindo o arquivo binário que recebemos como primeiro parâmetro // do nosso programa com permissão de leitura. if ( ( fd = open ( *++argv, O_RDONLY ) ) < 0 ) { perror ( "open" ); return EXIT_FAILURE; } // pulamos para o offset 0x3C para descobrir o offset do header PE. if ( lseek ( fd, 0x3c, SEEK_SET ) == -1 ) { perror ( "lseek 0x3c" ); close ( fd ); return EXIT_FAILURE; } // O offset tem 32 bits de tamanho! if ( read ( fd, &pe_pos, sizeof ( uint32_t ) ) <= 0 ) { close ( fd ); fputs ( "ERRO lendo do offset do header PE.\n", stderr ); return EXIT_FAILURE; } // Pula para o offset do header PE. if ( lseek ( fd, pe_pos, SEEK_SET ) == -1 ) { perror ( "lseek pe_hdr" ); close ( fd ); return EXIT_FAILURE; } // Le a assinatura PE (4 bytes)... if ( read ( fd, buffer, sizeof buffer ) <= 0 ) { close ( fd ); fputs ( "ERRO lendo do offset do PE header.\n", stderr ); return EXIT_FAILURE; } close ( fd ); // Mudei isso apenas para mostrar os 4 bytes lidos! show_buffer ( buffer, sizeof buffer ); return EXIT_SUCCESS; } // Mostra o conteúdo apontado por p (size bytes) // no formato de uma string em C. static void show_buffer ( void *p, size_t size ) { char *q; q = p; while ( size-- ) { if ( isprint ( *q ) ) putchar ( *q ); else printf ( "\\x%02hhx", *q ); q++; } putchar ( '\n' ); }
  20. PS2: O ponteiro para a lista de ponteiros para strings das variáveis de ambiente (envp) não é padrão ISO 9989... Algumas implementações aceitam: int main( int argc, char *argv[], char *envp[] ); Mas, prefira usar a função getenv() para obter o ponteiro envp acima, ao invés de usar essa declaração não padronizada (getenv() é definida no padrão POSIX).
  21. Ahhh... sim.. se formos obedecer à risca a especificação ISO 9989, o protótipo de main deve sempre ser: int main( int argc, char *argv[] ); // ou esse... int main( int argc, char **argv ); // ou esse, que é a mesma coisa! O nome dos argumentos pode ser qualquer um (count e args, por exemplo). O nome só é importante quando há um protótipo que force a definição (por isso não costumo prototipar com nomes de argumentos). No entanto, se sua função main não manipula os argumentos, ela pode ser declarada com uma lista de argumentos void. Mas, isso não é padrão! PS: O tipo de retorno, pelo padrão deve sempre ser int, mas você pode declarar como void se não estiver mesmo interessado no "errorlevel"... Mas, isso também não faz parte do padrão... Do ponto de vista do linker e co crt0.o (C Runtime object file - que é linkado junto com seu código), tudo o que interessa é o símbolo "main"... Já que, no padro de chamada cdecl quem manipula a pilha é o chamador, se main() receber ou não argumentos pela pilha, quem vai "limpá-la" é o crt0.o...
×
×
  • Create New...