Segfault nasm linux filekezelés C illesztéssel
2007-12-14T19:06:48+01:00
2007-12-16T18:37:33+01:00
2022-07-26T01:57:36+02:00
thorax
C-be illesztek NASM függvényt.

A C program a parancssori paramétert kapja meg, ami egy file-név, ezt adja át az assembly függvénynek, az assembly függvény pedig visszatér a file-ban található szavak számával.

Szerintem jól kéne működnie, de segmentation Faultot ad, viszont nem értem, hogy miért ott van a hiba, ahol...
gdb-vel való debuggolás után kiderült, hogy a visszatérésnél, a ret-nél száll el, de nem értem miért.
Szerintetek miért lehet?

próbálkoztam azzal, amit még nem teljesen értek:
a ret elé beillesztem:

mov esp,ebp
pop ebp

de így sem működik... Ez egyébként mit csinál?


a forráskódok:

-------------
foprog.c
-------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

extern int cw(char *a_bemeno_file_neve);

int main(int argc, char **argv){

int eredmeny=cw(argv[1]);

printf("\nA %s fileban %d szó van.\n", argv[1], eredmeny);

}


---------------
cw.asm
---------------
section .bss
buf resb 64
fd resb 4

section .text
global cw

cw:
push ebp
mov ebp,esp
mov ebx,[ebp+8] ;a file neve
jmp eleje

eleje:
mov eax,5 ;open()
;ebx-ben már a file neve van ;address of zero-terminated pathname
mov ecx,0 ;file access bits
;edx: file permission mode
int 80h ;a file descriptor elkészítése

cmp eax,0 ;ha hiba van az fd elkészítése során
jl hiba ;akkor ugorjon a hiba "ágra"

mov [fd],eax ;különben fd eax-be
jmp file_read ;ugrás a file olvasásra

file_read:

mov eax,3 ;read()
mov ebx,[fd] ;file descriptor
mov ecx,buf ;address of the buffer to read into
mov edx,64 ;maximum number of bytes to read
int 80h

cmp eax,0 ;number of bytes actually read
jl hiba ;ha 0 byteot olvasott, akkor hiba


mov edx,eax ;különben az olvasott byteok számát írja edx-be


;Cben a számláló függvény
;ret:=0;
;ecx:=edx; //azaz az olvasott byteok száma
;while ( ecx!=0){
; i:=0;
; if (buf==32) then //azaz ha Space karakter
; ret:=ret+1
; while (buf
==32){
; i:=i+1;
; }
;
; i:=i+1;
; dec ecx;
;}
;

;NASMBAN a számláló függvény:
;xor eax,eax ; a szó-számláló kinullázása
;mov ecx,edx ;a ciklusszámlálóba beírni a kiolvasott byteok számát
;ciklus:
; mov ebx,0
; cmp dword [buf+ebx],32
;
; je tovabb
;tovabb:
; inc eax
; jmp ciklus2
;ciklus2:
; inc ebx
; cmp dword [buf+ebx],32
; je ciklus2
; jmp folytat
;folytat:
; inc ebx
;loop ciklus



;a számlálás:
xor eax,eax ; a szó-számláló kinullázása
mov ecx,edx ;a ciklusszámlálóba beírni a kiolvasott byteok számát
ciklus:
mov ebx,0
cmp dword [buf+ebx],32

je tovabb
tovabb:
inc eax
jmp ciklus2
ciklus2:
inc ebx
cmp dword [buf+ebx],32
je ciklus2
jmp folytat
folytat:
inc ebx
loop ciklus
;a számlálás vége


cmp edx,64 ;ha megtöltötte a buffert az első olvasás, akkor még hosszabb is lehet akár a file, ezért olvassunk tovább!
je file_read

jmp vege ;különben biztosan vége a file-nak, így visszatérhetünk az eredménnyel

vege:
; mov esp,ebp
; pop ebp
ret

hiba:
mov eax,0
ret

--------------------------

fordítás:

nasm -felf cw.asm
gcc -o cw cw.o foprog.c

futtatás például:
./cw cw.asm

Előre is köszönöm a segítségetek!
Mutasd a teljes hozzászólást!
jmp eleje eleje:

Ezt tobb helyen hasznalod, oda ugrasz ahol vagy. nincs sok ertelme.

A te kodod. Melle irtam a hibakat
ciklus: mov ebx,0 ; cikluson belul nullazod ez megint nem jo cmp word [buf+ebx],32 ; miert word??? je tovabb ; ugyan oda ugrasz ahol vagy!!! tovabb: ; minden esetben noveled a szamlalot ;inc eax add word [words],1 ; inc eleg volna jmp ciklus2 ; megint egy felesleges JMP ciklus2: inc ebx ; elvi hiba a ciklus szamlot nem csokented a belso ciklusban cmp word [buf+ebx],32 ; miert word? UNICODE? je ciklus2 jmp folytat ; ez a jmp minek?? folytat: inc ebx loop ciklus ; felesleges ecx- es ebx parhuzamossan

A words sem szukseges van meg egy csomo regisztered
(ESI,EDI,EDX)

Ez az en kodom:

mov ebx,edx ; ebx-be szoveg hossza (hatulrol megyunk) mov ecx,0 ; ebbe szamuljuk a spaceok szamat ciklus: cmp byte [buf+ebx]," " ; szokoz karakter keresese jne nem_szokoz ; ha nem az akkor ugrunk inc ecx ; ha szokoz akkor novelunk nem_szokoz: szunet: ; vizsgaljuk hogy nincs-e dupla szunet dec ebx ; kovetkezo karakter es egyben ciklus szamalalo jc vege ; ha vegere ertunk cmp byte [buf+ebx]," " je szunet ; varjuk amig ujra betu lesz dec ebx ; pointer + ciklus szamlalo jnc ciklus ; ha van meg mit vizsgalni vege: ; eredmeny ecx-ben
Mutasd a teljes hozzászólást!

  • Ha asm-bol hivod meg a fuggvenyt, akkor is elszall?

    Szerk: paste-eld be ujbol a kodot, a forraskod gombot hasznalva!
    Mutasd a teljes hozzászólást!
  • azóta haladtam kicsit, mindjárt mondom, hoyg most mi nem jó :P :)

    cw.asm
    section .bss buf resb 64 fd resb 4 words resb 4 section .text global cw cw: push ebp mov ebp,esp mov ebx,[ebp+8] ;a file neve jmp eleje eleje: mov eax,5 ;open() ;ebx-ben már a file neve van ;address of zero-terminated pathname mov ecx,0 ;file access bits ;edx: file permission mode int 80h ;a file descriptor elkészítése cmp eax,0 ;ha hiba van az fd elkészítése során jl hiba ;akkor ugorjon a hiba "ágra" mov [fd],eax ;különben fd eax-be jmp file_read ;ugrás a file olvasásra file_read: mov eax,3 ;read() mov ebx,[fd] ;file descriptor mov ecx,buf ;address of the buffer to read into mov edx,64 ;maximum number of bytes to read int 80h cmp eax,0 ;number of bytes actually read jl hiba ;ha 0 byteot olvasott, akkor hiba mov edx,eax ;különben az olvasott byteok számát írja edx-be ;a számlálás: ;;;;;;;;;;;;;;; mov byte [words],0 ; a szó-számláló kinullázása ;;;;;;;;;;;;;;; mov ecx,edx ;a ciklusszámlálóba beírni a kiolvasott byteok számát ciklus: mov ebx,0 cmp word [buf+ebx],32 je tovabb tovabb: ;inc eax add word [words],1 jmp ciklus2 ciklus2: inc ebx cmp word [buf+ebx],32 je ciklus2 jmp folytat folytat: inc ebx loop ciklus ;a számlálás vége cmp edx,64 ;ha megtöltötte a buffert az első olvasás, akkor még hosszabb is lehet akár a file, ezért olvassunk tovább! je file_read jmp vege ;különben biztosan vége a file-nak, így visszatérhetünk az eredménnyel vege: ;;;;;;;;;;;;;;; mov eax,[words] ;;;;;;;;;;;;;; mov esp,ebp pop ebp ret hiba: mov eax,0 ret



    1bead.c
    #include <stdio.h> #include <stdlib.h> #include <string.h> int cw(char *a_bemeno_file_neve); int main(int argc, char **argv){ int eredmeny=cw(argv[1]); printf("\nA fileban %d szó van.\n", eredmeny); }
    Mutasd a teljes hozzászólást!
  • egyébként az volt a baj, hogy a futásiidejű veremből kiszedtem az argv[1]-et assemblyben, és utána ki akartam íratni Cben, így jóhogy nem ment neki :)

    most viszont a szószámlálás nem működik. Mivel eax-re szükségem van, ezért bevezettem a words -öt, és mielőtt ret -elek, beteszem eax-be a words tartalmát.

    csakhogy valamiért nem jó... nagyjából a sor hosszát adja vissza így a függvény.
    Mutasd a teljes hozzászólást!
  • jmp eleje eleje:

    Ezt tobb helyen hasznalod, oda ugrasz ahol vagy. nincs sok ertelme.

    A te kodod. Melle irtam a hibakat
    ciklus: mov ebx,0 ; cikluson belul nullazod ez megint nem jo cmp word [buf+ebx],32 ; miert word??? je tovabb ; ugyan oda ugrasz ahol vagy!!! tovabb: ; minden esetben noveled a szamlalot ;inc eax add word [words],1 ; inc eleg volna jmp ciklus2 ; megint egy felesleges JMP ciklus2: inc ebx ; elvi hiba a ciklus szamlot nem csokented a belso ciklusban cmp word [buf+ebx],32 ; miert word? UNICODE? je ciklus2 jmp folytat ; ez a jmp minek?? folytat: inc ebx loop ciklus ; felesleges ecx- es ebx parhuzamossan

    A words sem szukseges van meg egy csomo regisztered
    (ESI,EDI,EDX)

    Ez az en kodom:

    mov ebx,edx ; ebx-be szoveg hossza (hatulrol megyunk) mov ecx,0 ; ebbe szamuljuk a spaceok szamat ciklus: cmp byte [buf+ebx]," " ; szokoz karakter keresese jne nem_szokoz ; ha nem az akkor ugrunk inc ecx ; ha szokoz akkor novelunk nem_szokoz: szunet: ; vizsgaljuk hogy nincs-e dupla szunet dec ebx ; kovetkezo karakter es egyben ciklus szamalalo jc vege ; ha vegere ertunk cmp byte [buf+ebx]," " je szunet ; varjuk amig ujra betu lesz dec ebx ; pointer + ciklus szamlalo jnc ciklus ; ha van meg mit vizsgalni vege: ; eredmeny ecx-ben
    Mutasd a teljes hozzászólást!
  • Hello!

    Már sikerült azóta nekem is rájönnöm, hoyg össz-vissz igazándiból komoly hibám, ami miatt nem működött a program, egy helyen volt:

    a cmp műveleteknél word hosszan hasonlítottam össze, és nem byte, miután átírtam ezeket, működött a dolog...

    Azért köszi!
    Mutasd a teljes hozzászólást!
  • ja, ráadásul most látom, hogy egy régebbi kódot postoltam ide a fórumra... az újban már ki volt javítva több hiba is... bocsi, de nem aludtam sokat előtte... máskor jobban figyelek, mindenesetre a pont a tiéd, mert jó kódot írtál...
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd