[英]Assembly 32-bit program not waiting for user input after first time
我正在嘗試使用 x86 32 位系統調用編寫程序。 它應該設置一個結構數組,要求用戶輸入以填充結構x和y 。 感謝之前的評論,我相信我現在能夠獲得輸入來填充結構,但我似乎無法打印它們。 有人可以給我一個正確的方向嗎?
我知道需要修改輸入以打印正確的數字,但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.