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

yx2lnoni  于 2022-11-24  发布在  其他
关注(0)|答案(1)|浏览(103)

我正在尝试使用x86 32位系统调用编写一个程序。它应该建立一个结构数组,要求用户输入来填充结构 xy。感谢前面的评论,我相信我现在能够得到填充结构的输入,但我似乎不能打印它们。有人能给予我一个正确的方向吗?
我知道需要修改输入以打印正确的数字,但是 PrintDec 函数应该考虑到这一点。

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

这是我的代码和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
1szpjjfi

1szpjjfi1#

    • 错误#1:**您已经将counter定义为字节内存变量,但稍后在代码中将其视为DWORD。
counter:    db  5; keep track of how many input cycles are left
 ...
dec DWORD[counter]
    • 错误#2:**内核函数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。您应该将值读取到暂时缓冲区,将数字转换为二进制,然后才将其储存到数组中。

相关问题