繁体   English   中英

汇编 32 位程序在第一次后不等待用户输入

[英]Assembly 32-bit program not waiting for user input after first time

我正在尝试使用 x86 32 位系统调用编写程序。 它应该设置一个结构数组,要求用户输入以填充结构xy 感谢之前的评论,我相信我现在能够获得输入来填充结构,但我似乎无法打印它们。 有人可以给我一个正确的方向吗?

我知道需要修改输入以打印正确的数字,但PrintDec function 应该考虑到这一点。 我编译:

 nasm -f elf Lab_14.asm -o Lab_14.o and gcc -m32 -g -lc Lab_14.o -o Lab_14

这是我的代码和当前结果的屏幕截图

; Lab_14_Data_Structure

STRUC   Point       ;define Point structure
    .x: resb    4   ;reserve 4 bytes for x coordinate
    .y: resb    4   ;reserve 4 bytes for y coordinate
    .size:
ENDSTRUC

section .data
    msg1:       db  "Set the x and y coordinates of the five points",10,0
    msg1Len:    equ $-msg1
    
    msg2:       db  "Printing the X and Y coordinates for all points",10,0
    msg2Len:    equ $-msg2
    
    msg3:       db  "X = ",10,0
    msg3Len:    equ $-msg3
    
    msg4:       db  "Y = ",10,0
    msg4Len:    equ $-msg4
    
    msg5:       db  "Program completed successfully. Goodbye",10,0
    msg5Len:    equ $-msg5
    
    counter:    dd  5; keep track of how many input cycles are left
    
;declaring an instrance of Point structure and initalize its fields
P:ISTRUC Point
    AT Point.x, dd  0
    AT Point.y, dd  0
IEND

section .bss
PtArr:      resb    Point.size*5            ;reserve place for five structures
ArrCount:   equ ($-PtArr)/Point.size    ;five structures

section .text

    global main
    extern printf
    
main:
    ;start stack
    push    ebp
    mov ebp, esp
    
    mov ecx, ArrCount   ;count of array structures(5)
    mov esi, PtArr      ;points to beginning of array
    
    mov ecx, msg1
    mov edx, msg1Len
    call    PString

Input:
    ; get number from user to place in structures
    mov     ecx, msg3
    mov     edx, msg3Len
    Call PString
    
    mov eax, 3
    mov ebx, 0
    lea ecx, [esi+Point.x]
    mov edx, 4
    int 80h     
    
    mov     ecx, msg4
    mov     edx, msg4Len
    Call PString
    
    mov eax, 3
    mov ebx, 0
    lea ecx, [esi+Point.y]
    mov edx, 4
    int 80h
    
    add esi, Point.size     ;move to next structure in array
    dec DWORD[counter]
    cmp DWORD[counter], 0
    jne Input
    
        mov ecx, ArrCount   ;count of array structures(5)
    mov esi, PtArr      ;points to beginning of array
    mov DWORD[counter], 5   ;reset counter
PrintArray:
    mov eax, [esi+Point.x]
    call printDec
    call println

    mov eax, [esi+Point.y]
    call printDec
    call println
    
    add esi, Point.size
    dec DWORD[counter]
    cmp DWORD[counter], 0
    jne PrintArray
    
Exit:

    mov ecx, msg5
    mov edx, msg5Len
    call    PString
    
    mov esp, ebp
    pop ebp
    ret
    ;mov eax, 1
    ;mov ebx, 0
    ;int 80h

printDec:
    section .bss
        decstr      resb    10
        ct1     resd    1

    section .text
        pusha
        mov dword[ct1], 0
        mov edi, decstr
        add edi, 9
        xor edx, edx
    WhileNotZero:
        mov ebx, 10
        div ebx
        add edx, '0'
        mov byte[edi], dl
        dec edi
        inc dword[ct1]
        xor edx, edx
        cmp eax, 0
        jne WhileNotZero

        inc edi
        mov ecx, edi
        mov edx, [ct1]
        mov eax, 4
        mov ebx, 1
        int 80h

        popa
        ret

println:
    section .data
        nl  db  "",10
    section .text
        Pusha
        mov ecx, nl
        mov edx, 1
        mov eax, 4
        mov ebx, 1
        int 80h

        popa
        ret
        
PString:
    ;save register values
    pusha
    
    mov     eax, 4
    mov     ebx, 1
    int     80h
    
    ;restore old register values
    popa
    ret

错误 #1:您已将counter定义为字节 memory 变量,但稍后在代码中将其视为 DWORD。

counter:    db  5; keep track of how many input cycles are left
 ...
dec DWORD[counter]  

错误 #2: Kernel function read期望第二个参数(在ECX中传递)指向目标缓冲区,但您PtArr加载带有零的ECX

mov eax, 3                   ; Kernel function `sys_read`
mov ebx, 0                   ; File descriptor STDIN_FILENO=0
mov ecx, DWORD[esi+Point.x]  ; That is wrong!
LEA ECX,[ESI+Point.x]        ; Load its address instead.
mov edx, 4                   ; Size of Point.x=4
int 80h                      ; Invoke kernel

错误 #3:从键盘输入的坐标将输入的数字存储为十进制数字。 例如,当您将 x 坐标设置为1时, Point.x中的第一个字节将为0x31 您应该将值读取到临时缓冲区,将数字转换为二进制,然后才将其存储到数组中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM