2017-12-29 17 views
-1

Ich bekomme einen Segmentierungsfehler von diesem einfachen Startprogramm.Segmentierungsfehler in meinem Montageprogramm

Ich benutze Ubuntu 16.10 und kdbg zum Debuggen. Wenn Sie ab __int 80h__ erreichen, wird nicht mehr in die nächste Zeile gewechselt.

section .bss ; section containing uninitialized data 

BUFFLEN equ 1024 ; length of buffer 
Buff: resb BUFFLEN ; text buffer itself 

section .data ; section containing initialzed data 
section .text ; secttion containing code 

global _start ; linker needs to find the entry point! 

_start: 
    nop  ; this no-op keeps gdb happy 

    ; read buffer full of text form stdin: 
read: 
    mov eax, 3 ; specify sys_read call 
    mov ebx, 0 ; specify file descriptor 0 : standard input 
    mov ecx, Buff ; pass offset of the buffer to read to 
    mov edx, BUFFLEN ; pass number of bytes to be read at one pass 
    int 80h  ; call sys_read to fill the buffer 
    mov esi,eax  ; copy sys_read return value for safekeeping 
    cmp eax, 0 ; if eax = 0 , sys_read reached EOF on stdin 
    je Done  ; jump if Equal (to o, form compare) 


; set up the register for the process buffer step: 
    mov ecx, esi ; place the number of bytes read into ecx 
    mov ebp, Buff ; pace address of buffer into ebp 
    dec ebp   ; adjust the count to offset 

; go through the buffer and cnvert lowercase to uppercase characters: 
Scan: 
    cmp byte [ebp+ecx], 61h  ; test input char agaisnst lowercase 'a' 
    jb Next   ; if Below 'a' in ASCII, not lowercase 
    cmp byte [ebp+ecx], 7Ah  ; test against lowercase 'z' 
    ja Next 

    sub byte [ebx+ecx], 20h ; subtract 20h to give uppercase.. 

Next: 
    dec ecx ; Decrement counter 
    jnz Scan ; if characters reamin, loop back 

; Write the buffer full of processed text to stdout: 
Write: 
    mov eax,4 ; Specify sys_write call 
    mov ebx, 1 ; Specify file descriptor 1 : stdout 
    mov ecx, Buff ; pass the offset of the buffer 
    mov edx, esi ; pass the # of bytes of data in the buffer 
    int 80h  ; make sys_write kernel call 
    jmp read ; loop back and load another buffer full 

Done: 
    mov eax, 1 ; Code for Exit sys_call 
    mov ebx, 0 ; return code of Zero 
    int 80h 

benutzte ich diese Befehle:

nasm -f elf -g -F stabs uppercaser1.asm 
ld -m elf_i386 -o uppercaser1 uppercaser1.o 
./uppercaser < inputflie 
+0

bekommen Sie wirklich einen Segmentation Fault oder geht es weiter nicht (dh es l Ooks, als ob es hängt)? Das ist ein großer Unterschied. – PMF

+0

Ich empfehle, dass Sie Ihren Code über einen Debugger ausführen. Es sollte Ihnen sagen, wo in Ihrem Code dies abstürzt. benutze 'gdb./uppercaser1' zum Beispiel du hast' sub byte [ebx + ecx], 20h'. Ich denke du meinst "subbyte [ebp + ecx], 20h" zu benutzen? –

+0

Haben Sie versucht, ohne die externe Datei zu steuern (d. H. ./uppercaster InfinitelyManic

Antwort

0

Ich denke, dass dieser Code im Allgemeinen öffentlich ist, damit ich mit diesem Gedanken bin Entsendung.

Sie sollten den Code als Leitfaden verwenden, um zu verstehen, was in Ihrem Code möglicherweise falsch ist. es entspricht jedoch keinem Kodierungsstandard, so dass es sinnlos ist, sie einfach als eine Zuweisung zu kopieren und einzufügen; vorausgesetzt, das ist der Fall.

Sie werden Ihre Assemblerprogrammierfähigkeiten nie verbessern, indem Sie nur ein Kopieren/Einfügen ausführen.

lsb_release -a ... Beschreibung: Ubuntu 16.04.3 LTS

nasm -f elf32 -g uppercase1.s -o uppercase1.o & & ld -m elf_i386 uppercase1.o -o uppercase1

section .bss 
     Buff resb 1 

section .data 

section .text 
     global _start 
_start: 
     nop 

Read: 
     mov eax, 3    ; read syscall 
     mov ebx, 0    ; stdin 
     mov ecx, Buff   ; pass address of the buffer to read to 
     mov edx, 1    ; read one char or one byte 
     int 0x80    ; 

     cmp eax, 0    ; if syscall returns returns 0 
     je Exit     ; 

     cmp byte [Buff], 0x61 ; lower case a 
     jb Write    ; jump if byte is below a in ASCII chart 
     cmp byte [Buff], 0x7a ; lower case z 
     ja Write    ; jump if byte is above z in ASCII chart 

     sub byte [Buff], 0x20 ; changes the value in the buffer to an uppercase char 


Write: 
     mov eax, 4    ; write syscall 
     mov ebx, 1    ; stdout 
     mov ecx, Buff   ; what to print 
     mov edx, 1    ; length is one byte - each char is a byte 
     int 0x80 
     jmp Read    ; go back to Read 

Exit: 
     mov eax, 1 
     mov ebx, 0 
     int 0x80 

Beispielausgabe:

[email protected]:~/asm$ ./uppercase1 < uppercase1.s 
SECTION .BSS 
     BUFF RESB 1 

SECTION .DATA 

SECTION .TEXT 
     GLOBAL _START 
_START: 
     NOP 

READ: 
     MOV EAX, 3    ; READ SYSCALL 
     MOV EBX, 0    ; STDIN 
     MOV ECX, BUFF   ; PASS ADDRESS OF THE BUFFER TO READ TO 
     MOV EDX, 1    ; READ ONE CHAR OR ONE BYTE 
     INT 0X80    ; 

     CMP EAX, 0    ; IF SYSCALL RETURNS RETURNS 0 
     JE EXIT     ; 

     CMP BYTE [BUFF], 0X61 ; LOWER CASE A 
     JB WRITE    ; JUMP IF BYTE IS BELOW A IN ASCII CHART 
     CMP BYTE [BUFF], 0X7A ; LOWER CASE Z 
     JA WRITE    ; JUMP IF BYTE IS ABOVE Z IN ASCII CHART 

     SUB BYTE [BUFF], 0X20 ; CHANGES THE VALUE IN THE BUFFER TO AN UPPERCASE CHAR 


WRITE: 
     MOV EAX, 4    ; WRITE SYSCALL 
     MOV EBX, 1    ; STDOUT 
     MOV ECX, BUFF   ; WHAT TO PRINT 
     MOV EDX, 1    ; LENGTH IS ONE BYTE - EACH CHAR IS A BYTE 
     INT 0X80 
     JMP READ    ; GO BACK TO READ 

EXIT: 
     MOV EAX, 1 
     MOV EBX, 0 
     INT 0X80 
+0

danke Mann, aber ich habe es mit Puffer versucht –