FizzBu​​zz组装 - 段错误 [英] FizzBuzz in assembly - segmentation fault

查看:108
本文介绍了FizzBu​​zz组装 - 段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想写FizzBu​​zz在大会和我看到的分割故障所有的时间。到目前为止,我已经确定,这不是我的打印程序(因为我已删除的内容和问题依然存在),误差在主函数中的某处隐藏。

我得到这个输出,当我运行程序:

  fizzSegmentation故障

带领我相信它不是用分裂和仰视余的问题。但我可能是错的,我还没有在两年内完成大会...

 部分。数据
全球_start
    嘶嘶声:DB香味,4
    卖点:DB嗡嗡,4.bss段
    计数器:RESB 1.text段
_开始:    MOV AX,0
    MOV [计数器],斧中main_loop:    CMP AX,100;从0到100
    JE退出;
    MOV BL,3;除数
    MOV啊,0;这里将是一个余数
    DIV BL;鸿沟
    CMP啊,0;比较有剩余0
    JE print_fizz;如果等于打印嘶嘶声
    MOV BL,5;新除数
    MOV啊,0;我每次都做到这一点?
    DIV BL;鸿沟
    CMP啊,0;比较有剩余0
    JE print_buzz;如果等于打印的嗡嗡声
    JMP print_ax; AX如果没有打印内容
    INC斧头,斧头增量
    JMP中main_loop;跳转到标签print_ax:
    RETprint_fizz:
    RETprint_buzz:
    RET出口:
    MOV RAX,1
    MOV RBX,0
    INT 80H
    RET

我使用的编译:

  YASM -f ELF64 -o fizzbuzz.o fizzbuzz.asm
LD -d -o fizzbuzz fizzbuzz.o


解决方案

这是造成分段错误:

  ...
    JE print_fizz;如果等于打印嘶嘶声
...
    JE print_buzz;如果等于打印的嗡嗡声
    JMP print_ax; AX如果没有打印内容
...print_ax:
    RETprint_fizz:
    RETprint_buzz:
    RET
...

既然你跳到功能外, RET 没得到回信地址,并会在任何地方返回。将其更改为呼叫/ RET -pair:

  ...
; JE print_fizz;如果等于打印嘶嘶声
    JNE .1;跳过如果不相等
    调用print_fizz
    .1:
...; JE print_buzz;如果等于打印的嗡嗡声
    JNE 0.2;跳过如果不相等
    调用print_buzz
    0.2:; JMP print_ax; AX如果没有打印内容
    调用print_ax
...

这会导致一个无限循环:

  MOV AX,0
MOV [计数器],斧中main_loop:    CMP AX,100;从0到100
    JE退出
    ...
    MOV啊,0;这里将是一个余数
    DIV BL;鸿沟
    ...
    MOV啊,0;我每次都做到这一点?
    DIV BL;鸿沟
    ...
    INC斧头,斧头增量
    JMP中main_loop;跳转到标签

AX 改变其价值观,是不能胜任的循环计数器。我建议:

  ...
中main_loop:; CMP AX,100;从0到100
    CMP字节[计数器],100
...
; INC斧头,斧头增量
    INC字节[窗口]
    JMP中main_loop;跳转到标签
...

I am trying to write FizzBuzz in Assembly and I am seeing segmentation fault all the time. So far I have determined that it is not my printing routines (because I have removed their contents and the problem persists) and the error hides somewhere in the main function.

I was getting this output when I run the program:

fizzSegmentation fault

Leading me to believe that it's not the problem with using division and looking up the remainders. But I could be wrong, I haven't done Assembly in two years...

SECTION .data
global _start
    fizz: db "fizz", 4
    buzz: db "buzz", 4

SECTION .bss
    counter: resb    1

SECTION .text
_start:

    mov ax,0
    mov [counter],ax

main_loop:

    cmp ax,100          ;from 0 to 100
    je  exit            ;
    mov bl,3            ;divisor
    mov ah,0            ;here will be a remainder
    div bl              ;divide
    cmp ah,0            ;compare the remainder with 0
    je  print_fizz      ;print fizz if they equal
    mov bl,5            ;new divisor
    mov ah,0            ;do I have to do it every time?
    div bl              ;divide
    cmp ah,0            ;compare the remainder with 0
    je  print_buzz      ;print buzz if they equal
    jmp print_ax        ;print contents of ax if not
    inc ax              ;increment ax
    jmp main_loop       ;jump to label

print_ax:
    ret

print_fizz:
    ret

print_buzz:
    ret

exit:
    mov rax,1
    mov rbx,0
    int 80h
    ret

I am compiling using:

yasm -f elf64 -o fizzbuzz.o fizzbuzz.asm
ld -d -o fizzbuzz fizzbuzz.o

解决方案

This is causing the segmentation fault:

...
    je  print_fizz      ;print fizz if they equal
...
    je  print_buzz      ;print buzz if they equal
    jmp print_ax        ;print contents of ax if not
...

print_ax:
    ret

print_fizz:
    ret

print_buzz:
    ret
...

Since you jump to the functions, the ret gets no return address and will return anywhere. Change it to a call/ret-pair:

...
;   je  print_fizz      ;print fizz if they equal
    jne .1              ;skip if not equal
    call print_fizz
    .1:
...

;   je  print_buzz      ;print buzz if they equal
    jne .2              ;skip if not equal
    call print_buzz
    .2:

;   jmp print_ax        ;print contents of ax if not
    call print_ax
...

This will cause an infinite loop:

mov ax,0
mov [counter],ax

main_loop:

    cmp ax,100          ;from 0 to 100
    je  exit
    ...
    mov ah,0            ;here will be a remainder
    div bl              ;divide
    ...
    mov ah,0            ;do I have to do it every time?
    div bl              ;divide
    ...
    inc ax              ;increment ax
    jmp main_loop       ;jump to label

AX changes its values and is unfit to hold the loop-counter. I suggest:

...
main_loop:

;   cmp ax,100          ;from 0 to 100
    cmp byte [counter], 100
...
;   inc ax              ;increment ax
    inc byte [counter]
    jmp main_loop       ;jump to label
...

这篇关于FizzBu​​zz组装 - 段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆