String to int, C&ASM

Potrzebujesz pomocy z C, C++, perl, python, itp.
November
Posty: 5
Rejestracja: 21 marca 2008, 14:09
Lokalizacja: Kartuzy

String to int, C&ASM

Post autor: November »

Chcę zamienić stringa na inta, wpisuje dane w C, daje je do funkcji w ASM i wynik daje do C, gdzie go wyświetlam.

Kod: Zaznacz cały

#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ś

Kod: Zaznacz cały

gcc -S call.c
, by zobaczyć jak on to tam wysyła do rejestrów.

Kod: Zaznacz cały

	.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

Kod: Zaznacz cały

.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

Kod: Zaznacz cały

	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:

Kod: Zaznacz cały

 ./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
Beginner
Posty: 140
Rejestracja: 16 kwietnia 2007, 19:00
Lokalizacja: Legnica

Post autor: Theq »

Widać tam wyraźnie, że C wysyła mi jedynie pierwszą literę ze stringa :/
Ale o co chodzi? Masz przeciez suma(char a) a to jest jeden znak, wiec co ma wysylac ;)
Stawi
Beginner
Posty: 209
Rejestracja: 10 lutego 2007, 16:02
Lokalizacja: Kraków

Post autor: Stawi »

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
Posty: 10
Rejestracja: 26 listopada 2007, 23:48
Lokalizacja: E³k / Gdañsk

Post autor: painspr »

deklaracje funkcji zmień jak Stawi napisał czyli :

Kod: Zaznacz cały

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
ODPOWIEDZ