tcpipchip escreveu:
void calcula(unsigned char v1,v2)
{
return(v1+v2);
}
Não entendi o proposito do exemplo, mas isso ai nem compila.
tcpipchip escreveu:
void calcula(unsigned char v1,v2)
{
return(v1+v2);
}
#include <stdio.h>
int main()
{
int v;
v = calcula(2,3);
printf("%d\n",v);
}
void calcula(int v1, int v2)
{
int r;
r = v1+v2;
return r;
}
main:
link.w %a6,#-4 // reserva espaco para v, stack contem "a6 v"
pea 3.w // passa valor 3 para stack
pea 2.w // passa valor 2 para stack
jbsr calcula // chama funcao, veja ali embaixo! stack contem "a6 v 3 2 ret"
addq.l #8,%sp // joga fora os caras anteriores, stack contem "a6 v"
move.l %d0,-4(%a6) // salva em v valor retornado via d0
move.l -4(%a6),-(%sp) // empilha v, stack contem "a6 v v"
pea .LC0 // empilha string, stack contem "a6 v v *p"
jbsr printf // chama printf
addq.l #8,%sp // retorna stack ao que era: "a6 v", retorno de printf em d0 descartado.
move.l -4(%a6),%d0 // coloca retorno em d0
unlk %a6 // demonta estrutura de a6 e v, stack vazia
rts // retorna
calcula:
link.w %a6,#-4 // reserva espaco para r, stack contem "3 2 ret a6 r"
move.l 8(%a6),%d0 // puxa primeira variavel da stack
add.l 12(%a6),%d0 // puxa segunda variavel e soma
move.l %d0,-4(%a6) // salva soma em r
move.l -4(%a6),%d0 // retorna a funcao em d0 ???
unlk %a6 // desmonta reserva, ou seja, stack contem "3 2 ret"
rts // retorna, ou seja stack contem "3 2"
pushl %ebp // salva ebp na stack
movl %esp, %ebp // copia esp para ebp
pushl %ebx // salva ebx
subl $36, %esp // aloca espaco para 36 bytes?!?
call L3 // faz um call para ali embaixo
"L00000000001$pb": // soh deus sabe!!!
L3:
popl %ebx // desempilha ebx?!? pq? pq? pq? lah embaixo tb de novo?!? pq?
movl $3, 4(%esp) // salva valor 3 na stack
movl $2, (%esp) // salva valor 2 na stack
call L_calcula$stub // chama funcao calcula, acompanhe ali embaixo!
movl %eax, -12(%ebp) // deve ter retornado em eax... apesar de ser void?!? naoooooooooooooooo!!!
movl -12(%ebp), %eax // ele grava, retorna, eh uma salada...
movl %eax, 4(%esp) // empilha eax, finalmente
leal LC0-"L00000000001$pb"(%ebx), %eax // calcula o endereco da string...hmmmm
movl %eax, (%esp) // empilha o endereco da string, finalmente!!!
call L_printf$stub // chama printf
movl -12(%ebp), %eax // desaloca a salada acima
addl $36, %esp // desaloca os tais 36 bytes...
popl %ebx // recupera ebx... que ebx?!? nao saiu lah em cima jah?!?
leave // em teoria, similar a unlk do 68k
ret // retorna, finalmente! jah nao aguentava mais isso!
_calcula:
pushl %ebp // guarda ebp
movl %esp, %ebp // guarda esp em ebp
subl $24, %esp // aloca espaco para 24 bytes?!? enfim...
movl 12(%ebp), %eax // puxa o primeiro inteiro
addl 8(%ebp), %eax // soma com o segundo inteiro
movl %eax, -12(%ebp) // salva eax na stack em algum lugar...
leave // desmonta a salada
ret // e retorna
#include <stdio.h>
void calcula(int v1, int v2)
{
int r;
r = v1+v2;
return r;
}
int main()
{
int v;
v = calcula(2,3);
printf("%d\n",v);
}
$ gcc asm51/truta.c
asm51/truta.c:14: warning: conflicting types for ‘calcula’
asm51/truta.c:6: warning: previous implicit declaration of ‘calcula’ was here
asm51/truta.c: In function ‘calcula’:
asm51/truta.c:19: warning: ‘return’ with a value, in function returning void
$ ./a.out
5
extern int calcula(int, int);
int main()
{
int v;
v = calcula(2,3);
printf("%d\n",v);
}
void calcula(int v1, int v2)
{
int r;
r = v1+v2;
}
$ m68k-elf-gcc -c a.c
$ m68k-elf-gcc -c b.c
$ m68k-elf-ld a.o b.o
m68k-elf-ld: warning: cannot find entry symbol _start; defaulting to 80000074
$ file a.out
a.out: ELF 32-bit MSB executable, Motorola 68020, version 1 (SYSV), statically linked, not stripped
Marcelo Samsoniuk escreveu:a ocorrencia de underflow acho que depende da implementacao do compilador... no caso do gcc para 68k, realmente nao apenas nao ocorre, como tambem existem instrucoes do processador que conseguem desfazer qq salada que ocorra dentro da funcao chamada... eu verifiquei isso fazendo o codigo correto:
- Código: Selecionar todos
#include <stdio.h>
int main()
{
int v;
v = calcula(2,3);
printf("%d\n",v);
}
void calcula(int v1, int v2)
{
int r;
r = v1+v2;
return r;
}
gerando o assembler e analisando passo a passo:
colocar void com esse compilador em especial mostrou-se um problema: ele otimiza o codigo, verifica q nao tem o q retornar e suprime a funcao inteira! hehehe mas no gcc para x86 ele gera codigo... uma salada de codigo comparado ao 68k, mas com alguma dor e sofrimento eh possivel entender alguma coisa:
- Código: Selecionar todos
pushl %ebp // salva ebp na stack
movl %esp, %ebp // copia esp para ebp
pushl %ebx // salva ebx
subl $36, %esp // aloca espaco para 36 bytes?!?
call L3 // faz um call para ali embaixo
"L00000000001$pb": // soh deus sabe!!!
L3:
popl %ebx // desempilha ebx?!? pq? pq? pq? lah embaixo tb de novo?!? pq?
movl $3, 4(%esp) // salva valor 3 na stack
movl $2, (%esp) // salva valor 2 na stack
call L_calcula$stub // chama funcao calcula, acompanhe ali embaixo!
movl %eax, -12(%ebp) // deve ter retornado em eax... apesar de ser void?!? naoooooooooooooooo!!!
movl -12(%ebp), %eax // ele grava, retorna, eh uma salada...
movl %eax, 4(%esp) // empilha eax, finalmente
leal LC0-"L00000000001$pb"(%ebx), %eax // calcula o endereco da string...hmmmm
movl %eax, (%esp) // empilha o endereco da string, finalmente!!!
call L_printf$stub // chama printf
movl -12(%ebp), %eax // desaloca a salada acima
addl $36, %esp // desaloca os tais 36 bytes...
popl %ebx // recupera ebx... que ebx?!? nao saiu lah em cima jah?!?
leave // em teoria, similar a unlk do 68k
ret // retorna, finalmente! jah nao aguentava mais isso!
_calcula:
pushl %ebp // guarda ebp
movl %esp, %ebp // guarda esp em ebp
subl $24, %esp // aloca espaco para 24 bytes?!? enfim...
movl 12(%ebp), %eax // puxa o primeiro inteiro
addl 8(%ebp), %eax // soma com o segundo inteiro
movl %eax, -12(%ebp) // salva eax na stack em algum lugar...
leave // desmonta a salada
ret // e retorna
mas eh uma salada tao grande q nem acompanhando passo a passo se entende alguma coisa... se ele tambem passa como parametro, o void lah eh completamente ignorado, pq eax retorna o calculo e ele imprime na boa o resultado hehehe
Voltar para Visual C++/C/C++/C#
Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante