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



我正在尝试编写一个使用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

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

; 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定义为字节内存变量,但稍后在代码中将其视为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。你应该读入值到一个临时缓冲区,将数字转换为二进制,然后才将其存储到数组中。

相关内容

  • 没有找到相关文章

最新更新