[ASM][Linux][Intel] Kan bestand niet openen

Pagina: 1
Acties:

  • cxavier
  • Registratie: Maart 2006
  • Laatst online: 18:12
Ik ben nu een tijdje met assembly bezig, en nu zit ik met een probleempje. Het volgende stukje code werkt niet:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
section .data
    filename:   db '/home/frans/test.txt'

section .bss
    buffer:     resb 512    ; Reserveer 512 bytes

section .text
    global _start
_start:
    mov eax, 5          ; Open een bestand
    mov ebx, filename       ; ebx = filename
    mov ecx, 512            ; max 512 tekens
    int 0x80            ; kernel call


    mov ebx, eax            ; Zet de output (file descriptor) van
                    ; het openen in ebx
    mov eax, 3          ; sys call READ
                    ; ebx is al bekend
    mov ecx, buffer         ; schrijf het naar de buffer
    mov edx, 512            ; max 512 tekens
    int 0x80            ; kernel call

    mov eax, 4          ; system call write
    mov ebx, 1          ; standaard output
    mov ecx, buffer         ; print de buffer
    mov edx, 512            ; max 512 tekens
    int 0x80            ; kernel call

    mov eax, 1
    mov ebx, 0
    int 0x80

Het stukje code moet onder Linux draaien, met de intel-syntaxis. Als ik nasm en ld over de code laat gaan, en het programma uitvoer krijg ik geen output.

Het bestand /home/frans/test.txt bestaat wel, en er staat ook inhoud in (test).

Weet iemand wat ik verkeerd doe, en hoe ik het op zou kunnen lossen?

Knight who says 你


  • MrBucket
  • Registratie: Juli 2003
  • Laatst online: 29-10-2022
Ik heb vroeger wel een tijd Assembly geprogrammeerd voor DOS, maar dat is inmiddels wel redelijk weggezakt.

Geen idee of ik je nu de goede of de verkeerde kant opstuur, maar de volgende zaken vielen me op:
  1. Ik neem aan dat Linux ook vereist dat strings null-terminated zijn. Weet je zeker dat de declaratie van filename ook ervoor zorgt dat er een 0x00 achter geplakt wordt?
  2. Je gebruikt MOV om het adres van een variabele in te laden (bijv. "mov ebx, filename"), weet je zeker dat je niet de eerste vier bytes van filename inlaadt in plaats van het adres? Voor adressen gebruikte ik altijd "lea ebx, filename" (Load Effective Address). Geen idee of dit hetzelfde is, maar je kunt het altijd proberen.
  3. Is de file descriptor alleen platte tekst, of kunnen er ook nulls (0x00) tussenzitten? Waarschijnlijk print je kernel call op lijn 28 alleen tot de eerstvolgende null, nl.
  4. Het lijkt me dat ook Linux gebruik maakt van return-waarden. Als je precies wil weten waar je programma spaak loopt, gebruik een debugger en trace door je code heen (en let op de return-waarden van je calls).

  • Infinitive
  • Registratie: Maart 2001
  • Laatst online: 25-09-2023
Je kan dit probleem oplossen door wat extra instructies toe te voegen om het een en ander uit te testen. Test bijvoorbeeld eens of je een echte filehandle terugkrijgt (misschien faalt het open commando om een of andere reden toch). Of print eens een stringetje i.p.v. de 512 bytes die je in buffer hebt staan.

En wie weet wordt er onderwater ergens aan line-buffering gedaan (door je terminal o.i.d.) en krijg je nooit uitvoer te zien tenzij er een newline in je uitvoer zit...

putStr $ map (x -> chr $ round $ 21/2 * x^3 - 92 * x^2 + 503/2 * x - 105) [1..4]


  • alx
  • Registratie: Maart 2002
  • Niet online

alx

Als je een bestand opent, moet je geen size aangeven, maar de mode aangeven (read-only of read-write). Mss is er nog wel meer mis. Waarom gebruik je niet gewoon een tracer om stap voor stap het programma door te lopen en syscall return waarden te checken? Dat kan toch o.a. met gdb?

  • cxavier
  • Registratie: Maart 2006
  • Laatst online: 18:12
Nu werkt het wel :)
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
section .bss
    buffer:     resb 512    ; Reserveer 512 bytes

section .text
    global _start
_start:
    mov eax, 5          ; Open een bestand
    mov ebx, filename       ; ebx = filename
    mov ecx, 0          ; flag voor het lezen
    int 0x80            ; kernel call


    mov ebx, eax            ; Zet de output (file descriptor) van
                    ; het openen in ebx
    mov eax, 3          ; sys call READ
                    ; ebx is al bekend
    mov ecx, buffer         ; schrijf het naar de buffer
    mov edx, 512            ; max 512 tekens
    int 0x80            ; kernel call

    mov eax, 4          ; system call write
    mov ebx, 1          ; standaard output
    mov ecx, buffer         ; print de buffer
    mov edx, 512            ; max 512 tekens
    int 0x80            ; kernel call

    mov eax, 1
    mov ebx, 0
    int 0x80

Er stonden nog verschillende fouten in. bv dat de string null-terminated moest zijn (ik dacht dat dat alleen hoefde als je de string ging printen).

Met het programma strace heb ik idd de meeste fouten wel kunnen vinden :). Bedankt voor jullie hulp.

[ Voor 0% gewijzigd door cxavier op 18-06-2007 08:56 . Reden: Een stukje commentaar stond niet goed :P ]

Knight who says 你