ARM汇编实现保加利亚纸牌游戏遇段错误及冻结问题求助
保加利亚纸牌游戏ARM汇编程序调试问题
问题说明
我正在编写实现保加利亚纸牌游戏的ARM汇编程序:将45张“纸牌”随机分成若干堆(每堆数量随机),之后每次从每堆取1张组成新堆,当所有纸牌形成1、2、3、4、5、6、7、8、9的堆(顺序不限)时游戏结束。
程序打印初始设置后触发Segmentation Fault(段错误),GDB调试输出如下:
Program received signal SIGSEGV, Segmentation fault. 0xf7f831b8 in randtbl () from /lib/arm-linux-gnueabihf/libc.so.6
另外,当初始数组元素超过8个时,程序直接冻结。我已调试18小时仍无进展。
实现思路:先生成随机数组(已完成);每一步遍历数组,每个元素减1,随后执行打印数组、移除零元素、排序操作,检查是否符合1-9的堆形式,不符合则重复步骤。
代码实现
play.s
.cpu cortex-a72 .fpu neon-fp-armv8 .section .data finished: .asciz "We finished! Hooray!" labelPointerFour: .word 0 .section .text .extern printf .extern scanf .global startPlay .type startPlay, %function startPlay: @ Parameters: @ r0 = the address of the first location of the array @ r1 = the byte offset of the first unfilled byte of the array @ Uses: @ r0, r4, r5, r6, r7, r8 push {r4-r10, fp, lr} mov fp, sp @ initialization skipped: r4 is the address of the first element of the array, r5 is the offset, in bytes, assuming a number is 4 bytes of the last element, r6 is a copy of r4, and r9 is the last memory location in the array. playLoop: add r9, r4, r5 mov r8, #0 @ gives r8 a value of zero - it later gets used to be the new pile @ r6 is a modifiable copy of r4 and r8 is the counter representing the new pile mov r2, #0 @ r2 is the counter mov r6, r4 b innerPlayLoop innerPlayLoop: cmp r2, r5 @ if(counter >= offset){postPlay()} bge postPlay ldr r7, [r6] sub r7, r7, #1 add r8, r8, #1 str r7, [r6] @ increment counters add r6, r6, #4 add r2, r2, #4 b innerPlayLoop postPlay: str r8, [r9] mov r8, #1 @ r8 is what we are looking for in nexter mov r6, r4 @ establishing a solid copy of r4 mov r7, #0 @ the found flag push {r9} sub r9, r9, r4 cmp r9, r5 beq addermost nextGuy: pop {r9} push {r4, r5, r6} mov r0, r4 mov r1, r5 bl printArray pop {r4, r5, r6} push {r4, r5, r6} mov r0, r4 mov r1, r5, lsr #2 bl removeZero pop {r4, r5, r6} push {r4, r5, r6} mov r0, r4 mov r1, r5, lsr #2 bl sort pop {r4, r5, r6} b nexter @ important info going into nexter: @ r5 is the max offset @ r6 is a modifiable copy of r4 @ r7 is the found flag - make it 1 when you find something of a category @ r8 is the current number we're looking for @ r9 is the location of zero @ r2 is the current number's value @ r3 is the current offset @ if your search comes up empty, move to playLoop nexter: mov r7, #0 looperb: @ haha get it? like superb ok i'll stop add r8, r8, #1 mov r3, #0 @ everytime looperb runs, r3 goes to 0 mov r6, r4 looperc: ldr r2, [r6] add r6, r6, #4 add r3, r3, #4 cmp r2, r8 beq looperb cmp r8, #10 bne looperb cmp r8, #10 beq finishedPrinter b looperc addermost: add r5, r5, #4 add r9, r9, #4 b nextGuy finishedPrinter: ldr r0, =finished bl printf @ begin ending sequence mudithu: mov fp, sp b finisher pop {r4-r10, fp, pc}
printArray.s
.cpu cortex-a72 .fpu neon-fp-armv8 .section .data format: .asciz "%d " endFormat: .asciz "\n" .section .text .extern printf .extern scanf .global printArray .type printArray, %function printArray: @ Parameters: @ r0 = first memory address of array @ r1 = offset of first unfilled element of array @ Registers Used: @ r0, r1, r4, r5, r6 push {fp, lr} mov fp, sp mov r4, r0 @ r4 = current memory address of the element mov r5, #0 @ r5 = current offset mov r6, r1 @ r6 = max offset loopThrough: cmp r5, r6 @ if current offset >= max offset, end bge endPrint ldr r0, =format ldr r1, [r4] @ load element value bl printf add r4, r4, #4 @ move to next element add r5, r5, #4 @ increment current offset b loopThrough endPrint: ldr r0, =endFormat bl printf mov sp, fp pop {fp, pc}
genRanNum.s
.cpu cortex-a72 .fpu neon-fp-armv8 .section .data low: .word 50 high: .word 100 .section .text .extern time .extern printf .extern srand .extern rand .global genRanNum .type genRanNum, %function genRanNum: @ Input @ r0, the low bound @ r1, the high bound @ Registers used (maybe store them) @ r0, r1, r2, r3, r5 @ Returns @ r0: A random number between the entered r0 and r1, inclusive push {r4-r10, fp, lr} mov fp, sp mov r2, #0 mov r3, #0 mov r5, #0 ldr r3, =low str r0, [r3] ldr r3, =high str r1, [r3] mov r0, #0 bl time push {r0} bl srand pop {r0} bl rand @ r0 contains a big random number ldr r1, =low ldr r2, =high ldr r1, [r1] ldr r2, [r2] @ now start modulus division sub r5, r2, r1 add r5, r5, #1 modLoop: cmp r0, r5 blt addX sub r0, r0, r5 b modLoop addX: add r2, r0, r1 @ r2 now contains a random number between low and high mov r0, r2 mov sp, fp pop {r4-r10, fp, pc}
补充信息
已知错误出在play.s中,但GDB仅提示randtbl触发段错误。编译命令为:
gcc -o l4 *file names here* -g
内容的提问来源于stack exchange,提问作者anonsaicoder9
相关产品推荐
相关产品推荐

