Asembler x86/Łączenie z językami wysokiego poziomu/Moduły w języku C: Różnice pomiędzy wersjami

Usunięta treść Dodana treść
zapobieganie przed przepełnieniem bufora
użycie asemblera gnu
Linia 2:
// zawartość pliku str.c
#include <stdio.h>
extern unsigned int mystrlen (char *);
 
int main()
{
char tekstc[32];
printf("Wprowadź dowolny ciąg znaków..\n");
scanf("%31s",tekst c);
printf("Wprowadzony ciąg zawiera %d znaków.\n",mystrlen(tekstc));
return 0;
}
Linia 24:
 
<source lang="bash">
nasm -f elfas libfunmystrlen.asms -o libfunmystrlen.o
</source>
 
Linia 30:
 
<source lang="asm">
;/* zawartość pliku libfunmystrlen.asms
;
; zadeklarowaliśmy funkcję w C linkowaną statycznie
; extern unsigned int mystrlen(char *); , zatem:
; [EBP+8] zawiera wskaźnik pierwszego znaku
; [EBP+4] adres powrotu z funkcji
; [EBP] pierwotna wartość rejestru EBP
 
; zadeklarowaliśmy funkcję w C linkowaną statycznie
section .text
; extern unsigned int mystrlen(char *); , zatem:
global mystrlen
; [EBP+8] zawiera wskaźnik pierwszego znaku
; [EBP+4] adres powrotu z funkcji
; [EBP] pierwotna wartość rejestru EBP
*/
 
.text
.global mystrlen
 
mystrlen:
pushpushl %ebp ; tworzymy ramkę stosu
movmovl %ebp,%esp ; EBP = ESP (base pointer = stack pointer)
movmovl %esi,[%ebp+$8] ; ESI wskazuje teraz na pierwszy znak danego ciągu
xor %ecx,%ecx ; zerowanie rejestru ECX zliczającego znaki w ciąg
cld ; ustalenie kierunku odczytu znaków dla polecenia LODSB
 
petla:
xor %eax,%eax ; zerujemy EAX zanim pobierzemy kolejny znak
lodsb ; do rejestru AL pobierany jest znak [esi]
; indeks ESI zwiększany jest o 1
inc %ecx ; po każdym przebiegu ECX = ECX+1
 
or %eax,%eax ; jeżeli EAX różne od zera
jnz petla ; skok do "petla"
 
dec %ecx ; odjęcie końcowego znaku \0$ od wartości zliczonej w ECX
movmovl %eax,%ecx ; wynik funkcji umieszczany jest w EAX
 
movmovl %esp,%ebp ; niszczymy ramkę stosu, ESP=EBP
pop popl %ebp ; przywracamy pierwotną wartość EBP
ret ; koniec funkcji
</source>