2017-12-29 34 views
-1

この単純な開始プログラムからセグメンテーションフォルトが発生します。アセンブリプログラムのセグメンテーションフォルト

私はデバッグにUbuntu 16.10とkdbgを使用しています。到達点が__int 80h__に達すると、次の行への移動が停止します。

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 

私は、これらのコマンドを使用:

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

あなたが本当にセグメンテーションフォールトを取得してくださいか、それが継続していない(すなわち、それをLあたかも掛けているかのように)それは大きな違いです。 – PMF

+0

デバッガでコードを実行することをお勧めします。これはあなたのコードのどこでクラッシュするのかを教えてください。 'gdb。/ uppercaser1'を使ってください。たとえば、' sub byte [ebx + ecx]、20h'を実行してください。 'サブバイト[ebp + ecx]、20h'を使うと思いますか? –

+0

外部ファイル(例:./uppercaser InfinitelyManic

答えて

0

私はこのコードは一般公開されているので、私はこのことを念頭に置いて掲載していと思います。

コードで何が問題なのかを理解するためのガイドとしてコードを使用する必要があります。しかし、それはコーディング標準に準拠していないので、単にコピー&ペーストして割り当てとしてそれを入れ替えるのは無意味です。それがそうであると仮定して。

コピー/ペーストするだけでアセンブリのプログラミングスキルを向上させることは決してありません。

-a lsb_release ... 説明: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 

出力例:

[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

ありがとうございましたが、私はそれをバッファを使って試しました –

関連する問題