1

我正在为需要获取数组的作业编写汇编程序,比如说

array:  DB  1, 2, 3, 4, 5

我需要遍历它并打印与数组中的数字相对应的星号。所以在上面的例子中,程序应该输出:

* * * * *
  * * * *
    * * *
      * *
        *

我的问题是我在代码的某个地方遇到了分段错误,我无法确定在哪里。有人知道这发生在哪里吗?

代码:

%INCLUDE    "csci224.inc"

SEGMENT     .data
array:      DB      1, 2, 3, 4, 5, 4, 3, 2, 1
star:       DB      "*",0,10
n:          DB      0

SEGMENT     .text
main:
    mov         edx, 9                  ;length of array
    mov         ecx, 0                  ;loop counter
    jmp         outerloop               ;begin outerloop

outerloop:

    mov         ah, [array+ecx]         ;move (array element + loop counter) to ah

    movzx       ebx, ah                 ;zero extend ah to ebx
    mov         [n], ebx                ;copy value of array element to variable
    mov         eax, ebx

    inc         ecx

    ;call       WriteInt    
    dec         edx
    jnz         innerloop               ;jump to innerloop

innerloop:                              ;cycle through '[n]', printing a star each time
        mov     edi, [n]
        mov     eax, [star]
        call    WriteString             ;print star
        dec     edi                     ;decrement counter
        jnz     innerloop               ;is edi zero? if no, loop again
        cmp     ecx, byte 0             ;if yes, go back to outerloop
        jz      outerloop


    ret
4

1 回答 1

1

First off, the ret you have at the end, is not the correct way to end your program! In Windows, you would use ExitProcess or call exit if you are linking to the C library. In Linux, you would use int 80H - sys_exit or syscall - 60 or exit if you are linking to the C Library.

When using nested loops, first get your outer loop working first; print out each value in the array. Once you have that working, add your "inner" loop to print the stars.

In the following code, I use esi and ebx since those must be saved by the callee so we shouldn't need to worry about saving those values.

extern printf, exit
global main

SEGMENT     .data
array:      DB      1, 2, 3, 4, 5, 4, 3, 2, 1
array_len   equ     $ - array
star:       DB      "*", 0

SEGMENT     .text
main:
    mov     esi, 0                  ;loop counter

.ArrayLoop:
    ;~ Get array value to use as PrintStars loop counter, esi is index into array
    movzx   ebx, byte [array + esi]
    ;~ increase ArrayLoop "Outer Loop" counter
    inc     esi
    cmp     esi, array_len
    ;~ if esi > array_len, we are done
    jg      .Done   

.PrintStars:
    ;~ print stars here

    ;~ decrease "Inner Loop" counter
    dec     ebx
    ;~ If ebx != 0, continue "Inner Loop"
    jnz     .PrintStars

    ;~ ebx == 0, print new line char and continue "Outer Loop"    
    ;~ print newline char here
    jmp     .ArrayLoop

.Done:
    call    exit

Which would print out the stars as: Star thing according to the array in your source.

If you wanted to make a pyramid, read this

于 2013-10-06T05:08:44.310 回答