ďťż
 
 
   String to int, C&ASM
 
 

Tematy

 
    
 

 

 

 

String to int, C&ASM





November - 06-04-2008 19:24
Chcę zamienić stringa na inta, wpisuje dane w C, daje je do funkcji w ASM i wynik daje do C, gdzie go wyświetlam.

#include <stdio.h>

extern char suma (char a);

int main(void)
        {
        char g[100] = { "Programowanie" };
        printf("podaj jakas wart: ");
        scanf("%s", g);
        printf("%s\n", g);

        printf("%d\n",        suma (*g));
        return 0;
} Mam taki kod w C, teraz go sobie zrobiłem takie coś
gcc -S call.c , by zobaczyć jak on to tam wysyła do rejestrów.
        .file        "call.c"
        .section        .rodata
.LC1:
        .string        "podaj jakas wart: "
.LC2:
        .string        "%s"
.LC3:
        .string        "%d\n"
.LC0:
        .string        "Programowanie"
        .zero        86
        .text
.globl main
        .type        main, @function
main:
.LFB2:
        pushq        %rbp
.LCFI0:
        movq        %rsp, %rbp
.LCFI1:
        subq        $112, %rsp
.LCFI2:
        movq        .LC0(%rip), %rax
        movq        %rax, -112(%rbp)
        movl        .LC0+8(%rip), %eax
        movl        %eax, -104(%rbp)
        movzwl        .LC0+12(%rip), %eax
        movw        %ax, -100(%rbp)
        leaq        -98(%rbp), %rdi
        movl        $86, %edx
        movl        $0, %esi
        call        memset
        movl        $.LC1, %edi
        movl        $0, %eax
        call        printf
        leaq        -112(%rbp), %rsi
        movl        $.LC2, %edi
        movl        $0, %eax
        call        scanf
        leaq        -112(%rbp), %rdi
        call        puts
        movzbl        -112(%rbp), %eax
        movsbl        %al,%edi
        call        suma
        movsbl        %al,%esi
        movl        $.LC3, %edi
        movl        $0, %eax
        call        printf
        movl        $0, %eax
        leave
        ret
.LFE2:
        .size        main, .-main
        .section        .eh_frame,"a",@progbits
.Lframe1:
        .long        .LECIE1-.LSCIE1
.LSCIE1:
        .long        0x0
        .byte        0x1
        .string        "zR"
        .uleb128 0x1
        .sleb128 -8
        .byte        0x10
        .uleb128 0x1
        .byte        0x3
        .byte        0xc
        .uleb128 0x7
        .uleb128 0x8
        .byte        0x90
        .uleb128 0x1
        .align 8
.LECIE1:
.LSFDE1:
        .long        .LEFDE1-.LASFDE1
.LASFDE1:
        .long        .LASFDE1-.Lframe1
        .long        .LFB2
        .long        .LFE2-.LFB2
        .uleb128 0x0
        .byte        0x4
        .long        .LCFI0-.LFB2
        .byte        0xe
        .uleb128 0x10
        .byte        0x86
        .uleb128 0x2
        .byte        0x4
        .long        .LCFI1-.LCFI0
        .byte        0xd
        .uleb128 0x6
        .align 8
.LEFDE1:
        .ident        "GCC: (GNU) 4.2.3 (Debian 4.2.3-3)"
        .section        .note.GNU-stack,"",@progbits Widać tam wyraźnie, że C wysyła mi jedynie pierwszą literę ze stringa :/
movzbl -112(%rbp), %eax
movsbl %al,%edi

Mam taka funkcję w asm dla gcc
.globl suma
        .type        suma, @function
suma:
        #ramka
        pushq        %rbp
        movq        %rsp, %rbp
        #koniec ramki
       
        movl        %edi, -4(%rbp)
        movl        -4(%rbp), %eax
       
        #wyjscie
        leave
        ret
        .size        fun, .-fun Bądź taką dla NASM'a
        section .text ;use64

        global        suma

        suma:
;############## Rozpoczęcie ramki
                push        rbp
                mov        rbp, rsp
;############## Wyświetlenie liczby ramki

                mov        [rbp-4], edi
                mov        eax, [rbp-4]

;############## Zakończenie ramki
                leave
                ret Efekt działa takiego programu to:
./suma
podaj jakas wart: rty
rty
114

$ ./suma
podaj jakas wart: r
r
114 Czyli widać dokładnie to, że wysyła tylko jedną literę... A może wysyła wszystkie, tylko gdzie one wtedy są? :shock:



Theq - 07-04-2008 00:08
Ale o co chodzi? Masz przeciez suma(char a) a to jest jeden znak, wiec co ma wysylac ;)



Stawi - 07-04-2008 19:21
Po pierwsze: extern char suma (char *a);

Po drugie widac wyraznie ze nic nie idzie na petli wiec jak ma zliczac nastepne znaki? Przesuwaj wskaznik (zwiekszaj rejestr) az wartosc na ktora pokazuje bedzie rowna zero (czyli koniec stringa).



painspr - 09-04-2008 22:57
deklaracje funkcji zmień jak Stawi napisał czyli :
extern suma(char *g); i wywołuj suma(g), jak dasz operator * to pobierze wartość z adresu wskazywanego przez wskaźnik, a nazwa tablicy jest właśnie wskaźnikiem

i wydaje mi się, że parametry chyba zaczynają się od [ebp-8] (u Ciebie [rbp-8]) bo jeszcze ślad funkcji jest na stosie albo jeszcze lepiej [rbp-12] bo rbp jest chyba 8 bajtowy, nie wiem jak jest ze śladem na 64bitowych, czy jest też 64bitowy
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • minister.pev.pl

  •  

     


     

     
    Copyright 2003. MĂłj serwis