如何对汇编x86中堆栈中元素的所有ascii值求和

问题描述 投票:0回答:1

此时我感到很失落,这就是为什么我的代码看起来像这样

org 100h

start:
    xor ax, ax          
    xor dx, dx          
    mov ah, 1           
    xor cx, cx          

input:
    int 21h             
    cmp al, '+'         
    jz sum          

    push ax             
    inc cx              
    jmp input      

sum:
    push bp              
    mov bp, sp           
    mov cx, [bp+4]       
    mov si, 6            
    xor ax, ax          

sum_loop:
    push bp
    mov bp, sp
    mov ax, [bp+6]
    mov bx, [bp + 4]
    add ax, bx
    mov [result], ax
    pop ax
    loop sum_loop 
    pop bp; 
    ret

print:
    mov al, [result]
    mov bl, 10
    div bl
    mov [pt_one], ah
    
    xor ah, ah
    
    div bl
    mov [pt_two], ah
    xor ah, ah
    
    add al, 48
    mov dl, al
    mov ah, 2
    int 21h
    
    mov al, [pt_two]
    add al, 48
    mov dl, al
    mov ah, 2
    int 21h
    xor al, al
    
    mov al, [pt_one]
    add al, 48
    mov dl, al
    mov ah, 2
    int 21h
    
    mov ax, 4c00h
    int 21h
    
section .data
    pt_one db 1
    pt_two db 1
    result db 0

在这里,我确信输入部分正在工作,但我无法弄清楚这是我的求和协议错误还是我的打印方式不好。总结起来,我尝试添加 2 个下一个元素并将其添加到结果变量中,然后删除堆栈顶部。当我尝试这段代码时(通常我输入 123+)并且我输入 + 没有任何反应,坦率地说我不知道如何修复它。

assembly nasm x86-16
1个回答
0
投票

一个问题是由

ret
指令引起的。
ret
从堆栈中弹出地址并将其加载到程序计数器中。但你永远不会将此代码作为函数,因此堆栈不包含任何有效的返回地址。程序跳转到“随机”地址,特别是 0100h 与
call
之前最后一个输入字符的 ASCII 代码进行或运算。如果您的输入是
+
,则虚假地址是
123+
。碰巧有
0133h
指令,所以
mov bl, 10
就被跳过了。然后
mov al, [result]
尝试将
div bl
除以
ax
,但
10
值取决于初始
ax
值(在
bp
/
push bp
之后),该值通常是未定义的。
代码还有另一个问题:

压入堆栈的值是 16 位字,低字节包含 ASCII 码,高字节包含 01h。您将它们添加为包括高字节的 16 位字,然后将
    pop ax
  • 中的结果 16 位值除以
    ax
    。我想这不是你想要的。
    如果在
  • 10
  • 之前没有输入任何字符,
    +
    将进行65536次迭代。
    等等...
  • 程序可以简化:将临时值保存在寄存器中,而不是存储到内存中。我假设目标是显式地迭代堆栈,而不需要对值进行
loop

ing 或直接在每个输入迭代上添加它们而不将它们存储到内存中。在这种情况下,完整的程序可以如下:

pop

	
© www.soinside.com 2019 - 2024. All rights reserved.