簡體   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