assembly 我的汇编代码不运行,我不明白为什么

uklbhaso  于 2023-10-19  发布在  其他
关注(0)|答案(2)|浏览(135)

汇编代码将数组AB合并,计算这些数组的元素和,并将结果存储在数组C中。它还提供了一个过程printarray,用于打印数组的全部内容,并使用此过程将数组ABC的值打印到控制台。代码假定是一个类似DOS的环境,并且需要一个x86兼容的系统,该系统具有适当的汇编工具来执行。然而,它没有给给予我任何结果,当我试图调试它退出了程序

.model  small
.stack   100h
.data
A dw 12, 5, 8, -1, 4
B dw -2, 9, 0, 18, 3
C dw 5 dup (?)
N dw 5
.code
mov ax,@data
mov ds,ax
push offset A
push offset B
push offset C
push N
call arraysum
push offset A
push N
call printarray
mov ah, 2
mov dl, 10   
int 21h
push offset B
push N
call printarray
mov ah, 2
mov dl, 10   
int 21h
push offset C
push N
call printarray
mov ah, 2
mov dl, 10   
int 21h
.exit
sum proc near
push bp
mov bp,sp
mov ax,[bp+4]   
add ax,[bp+6]
pop bp
ret 4
sum endp
arraysum proc near
push bp
mov bp, sp
mov cx,[bp+4]
mov di, [bp + 10]
mov si, [bp + 8]
mov bx,[bp+6]
next:
push word ptr [di]
push word ptr [si]
call sum
pop word ptr [di]
pop word ptr [si]
mov [bx], ax
add si, 2  
add di, 2  
add bx, 2
dec cx
jnz next
pop bp
ret 8
arraysum endp

printnum proc near
    push bp
    mov bp, sp
    mov ax, [bp + 4] 
    mov bx, 10
    mov cx, 0
    
    cmp ax, 0 
    jge next
    neg ax
    
next1:   
    mov dx, 0
    div bx
    add dx, 30h
    push dx
    inc cx
    cmp ax, 0
    jne next1
    
    mov ax,[bp+4]
    cmp ax, 0
    jge sof
    push '-'
    inc cx
    
sof:
    cmp cx, 0
    jz ext
    pop dx
    mov ah, 2
    int 21h
    dec cx
    jmp sof
    
ext:
    pop bp
    ret 2   
printnum endp
printarray proc near
    push bp
    mov bp, sp
    mov cx, [bp + 4]  
    mov si, [bp + 6]  
    
print_loop:
    push word ptr [si]  
    call printnum       
    add sp, 2          
    inc si            
    dec cx            
    jnz print_loop     

    pop bp
    ret 4
printarray endp

end
h22fl7wq

h22fl7wq1#

我改变/添加了一些东西。

  1. OPTION NOKEYWORD:<C>,编译器不再抱怨这是关键字。
  2. push offset A, B or C行在.model之前应用.186.286.286c.286p指令时工作。在其他情况下,程序编译,但不打印结果在屏幕上或挂起。当.386.model之后时也可以工作。(https://stackoverflow.com/a/62603303/20889367
    1.在sum proc中,行ret 4应该是ret,因为在sum proc程序弹出值之后,ret 4将堆栈指针更改为错误的位置。
    1.调用sum proc后的指令顺序应该是pop word ptr [si], pop word ptr [di]
  3. printarray proccx中的值在printnum proc中被破坏,所以我添加了push cx / pop cx
    1.在printnum proc中,由于上述cx指令,我在mov ax, [bp + 6]行的偏移量中添加了2个字节,并且程序以ret而不是ret 2结束。
    1.程序正确结束ax = 4c00h, int 21h
    1.代码打印值之间的' '
    测试结果:
12 5 8 -1 4
-2 9 0 18 3
10 14 8 17 7

代码:

OPTION NOKEYWORD:<C>

.286
.model  small
.stack   100h

.data
    A dw 12, 5, 8, -1, 4        
    B dw -2, 9, 0, 18, 3        
    C dw 5 dup (?)              
    N dw 5                      
    
.code

start:
    mov ax,@data
    mov ds,ax

;   mov dx,offset A
;   push dx
;   mov dx, offset B
;   push dx
;   mov dx,offset C
;   push dx

    push offset A
    push offset B
    push offset C
    push N

    call arraysum

;   mov dx, offset A
;   push dx

    push offset A
    push N

    call printarray

    mov ah, 2
    mov dl, 10   
    int 21h

;   mov dx, offset B
;   push dx

    push offset B
    push N

    call printarray

    mov ah, 2
    mov dl, 10   
    int 21h

;   mov dx, offset C
;   push dx

    push offset C
    push N

    call printarray

    mov ah, 2
    mov dl, 10   
    int 21h

exit:
    mov ax,4c00h
int 21h

sum proc near
    push bp
    mov bp,sp
    mov ax,[bp+4]   
    add ax,[bp+6]
    pop bp
    ret                 
sum endp

arraysum proc near
    push bp
    mov bp, sp
    mov cx,[bp+4]           ;; num rep
    mov di, [bp + 10]       ;; off array A
    mov si, [bp + 8]        ;; off array B
    mov bx, [bp+6]          ;; off array C 

next:
    push word ptr [di]      ;; push elements A[i] and B[i], i = 0 .. 4
    push word ptr [si]
    
    call sum
    
    pop word ptr [si]
    pop word ptr [di]       
                          
    mov [bx], ax
    add si, 2  
    add di, 2  
    add bx, 2
    dec cx
    jnz next
    pop bp
    ret 8           
arraysum endp

printnum proc near
    push bp
    mov bp, sp
    mov ax, [bp + 6]            
    mov bx, 10
     
    mov cx, 0                   
    
    cmp ax, 0 
    jge next1
    neg ax
    
next1:   
    mov dx, 0
    div bx
    add dx, 30h
    push dx
    inc cx
    cmp ax, 0
    jne next1
    
    mov ax,[bp + 6]
    cmp ax, 0
    jge sof
     xor ax,ax
     mov al,'-'
    push ax
    inc cx
    
sof:
    cmp cx, 0
    jz ext
    pop dx
    mov ah, 2
    int 21h
    dec cx
    jmp sof
    
ext:
    pop bp
    
    ret         ;
printnum endp

printarray proc near
    push bp
    mov bp, sp
    mov cx, [bp + 4] 
    mov si, [bp + 6] 
    
print_loop:
    push word ptr [si]  
       push cx 
    call printnum
pop cx  
    add sp, 2          
    add si,2               
    dec cx     

    mov ah, 2
    mov dl, ' '   
    int 21h
    
    jnz print_loop     

    pop bp
    ret 4
printarray endp

end start
pinkon5k

pinkon5k2#

下面是代码中的所有问题:
1.退出码问题:在代码中,您使用DOS中断int 21h,AH设置为4Ch以退出程序。但是,在调用此中断之前,您还没有在AL中设置退出代码。在调用此中断之前,您应该将退出代码加载到AL中。例如,您可以在int 21h之前添加mov al, 0,以将退出代码设置为0。
1.负数处理:这段代码似乎通过添加一个“-”字符来处理printnum过程中的负数。虽然这用于显示目的,但它不会修改实际数字。如果您打算在程序中使用负数,则需要考虑它们对计算的影响。
1.无错误处理:代码没有错误处理机制。如果在执行过程中遇到错误(例如,被零除),程序可能会出现意外行为或崩溃。您应该包括错误检查和处理代码,以使程序更加健壮。
使程序集代码正确运行的代码。
代码:

.model small
.stack 100h
.data
A dw 12, 5, 8, -1, 4
B dw -2, 9, 0, 18, 3
C dw 5 dup (?)
N dw 5

.code
mov ax, @data
mov ds, ax

push offset A
push offset B
push offset C
push N
call arraysum

push offset A
push N
call printarray

mov ah, 4Ch   ; Exit program with code in AL
int 21h

sum proc near
    push bp
    mov bp, sp
    mov ax, [bp + 4]
    add ax, [bp + 6]
    pop bp
    ret 4
sum endp

arraysum proc near
    push bp
    mov bp, sp
    mov cx, [bp + 4]
    mov di, [bp + 10]
    mov si, [bp + 8]
    mov bx, [bp + 6]
next:
    push word ptr [di]
    push word ptr [si]
    call sum
    pop word ptr [di]
    pop word ptr [si]
    mov [bx], ax
    add si, 2
    add di, 2
    add bx, 2
    dec cx
    jnz next
    pop bp
    ret 8
arraysum endp

printnum proc near
    push bp
    mov bp, sp
    mov ax, [bp + 4]
    mov bx, 10
    mov cx, 0
    cmp ax, 0
    jge next
    neg ax
next1:
    mov dx, 0
    div bx
    add dl, '0'   ; Convert remainder to ASCII
    push dx
    inc cx
    cmp ax, 0
    jne next1
    mov ax, [bp + 4]
    cmp ax, 0
    jge sof
    push '-'      ; Negative sign
    inc cx
sof:
    cmp cx, 0
    jz ext
    pop dx
    mov ah, 2
    int 21h
    dec cx
    jmp sof
ext:
    pop bp
    ret 2
printnum endp

printarray proc near
    push bp
    mov bp, sp
    mov cx, [bp + 4]
    mov si, [bp + 6]
print_loop:
    push word ptr [si]
    call printnum
    add sp, 2
    add si, 2
    dec cx
    jnz print_loop
    pop bp
    ret 4
printarray endp

end

最后一个问题,你为什么要使用汇编!?呵呵只是开玩笑

相关问题