简体   繁体   中英

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

I am trying to write a program using system calls for x86 32-bit. It is supposed to set up an array of structures that ask for user input to fill in the structures x and y . Thanks to previous comments, I believe I am able to get the inputs to populate the structures now, but I can't seem to print them. Can someone give me a push in the right direction please?

I know that the inputs need to be modified to print the right number, but the PrintDec function should account for this. I compile with:

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

Here's my code and a screenshot of my current results

; 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

Error #1: You have defined counter as a byte memory variable, but later in code you treat it as DWORD.

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

Error #2: Kernel function read expects the 2nd argument (delivered in ECX ) to point at the target buffer, but instead you load ECX with zeros from PtArr .

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

Error #3: Coordinates input from keyboard stores the input number as decimal digits. When you set for instance the x coordinate as 1 , the first byte in Point.x will be 0x31 . You should read the values to a temporary buffer, convert the number to binary and only then store it to the array.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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