我刚开始处理结构点,这很令人困惑。
程序应该让用户输入5个值,将其保存在STRUC Point中,然后返回值。
“read_loop”读取用户输入并将其发送到readInt以转换为ASCII,然后当返回时,使用“mov [esi + Point.x],eax”和“mov [esi + Point.y],eax”保存,然后“read_loop应该在循环中打印出这些值。
这是预期的输出。
Enter x and y values for point:
53
6
Enter x and y values for point:
3
6
Enter x and y values for point:
3
6
Enter x and y values for point:
3
6
Enter x and y values for point:
3
6
Point values:
53
6
Point values:
3
6
Point values:
3
6
Point values:
3
6
Point values:
3
6
但是这是我得到的输出
Enter x and y values for point:
53
6
Enter x and y values for point:
3
6
Enter x and y values for point:
3
6
Enter x and y values for point:
3
6
Enter x and y values for point:
3
6
Point values:
Point values:
Point values:
Point values:
Point values:
由于某种原因,它要么没有正确存储值,要么没有正确获取值?我已经尝试了几个小时来解决这个问题,我试图扰乱ALIGN,我看不出是什么原因导致值没有被返回。
下面是完整的代码
STRUC Point ; define point structure
.x: RESD 1 ;reserve 4 bytes for x coordinate
.y: RESD 1 ;reserve 4 bytes for y coordinate
.size:
ENDSTRUC
section .data
enter_msg db 'Enter x and y values for point: ',10, 0
enter_msg_len: equ $-enter_msg
space db ' ', 0
output_msg db 'Point values: ', 10, 0
output_msg_len: equ $-output_msg
section .bss
PtArr: RESB Point.size*5 ; reserve place for 5 structures
ArrCount: EQU ($-PtArr) / Point.size ; Should be 5 structures
section .text
global _start
_start:
push ebp ; Save ebp for whoever called main function (OS or other program)
mov ebp, esp ; Create our new stack frame
; Initialize esi register to point to the start of PtArr
lea esi, [PtArr]
mov ebx, 5 ; Initialize loop counter with the desired number of iterations
read_loop:
mov ecx, enter_msg ; Print message #1
mov edx, enter_msg_len
call printString
; Read x value
call readInt
mov [esi + Point.x], eax
; Debugging print statement
mov ecx, [esi + Point.x]
call printDec
call printNewLine
; Read y value
call readInt
mov [esi + Point.y], eax
; Debugging print statement
mov ecx, [esi + Point.y]
call printDec
call printNewLine
add esi, Point.size ; Increment pointer to next structure in array
add esi, Point.size ; Increment pointer to next structure in array
dec ebx ; Decrement loop counter
jnz read_loop ; Jump to beginning of loop if counter is not zero
jmp prepare_print_loop ; Jump to prepare_print_loop to reset esi and then jump to print_loop
jmp prepare_print_loop ; Jump to prepare_print_loop to reset esi and then jump to print_loop
prepare_print_loop:
; Reset esi to point to the start of PtArr
lea esi, [PtArr]
; Initialize loop counter with the desired number of iterations (5 in this case)
sub ebx, ebx
mov ebx, 5
; Debugging print loop
mov ecx, output_msg ; Print message #2
mov edx, output_msg_len
call printString
mov ecx, [esi + Point.x]
call printDec
mov ecx, space
call printString
mov ecx, [esi + Point.y]
call printDec
call printNewLine
print_loop:
; Display output message
mov ecx, output_msg ; Print message #2
mov edx, output_msg_len
call printString
; Save the value of esi
push esi
; Print x value
mov eax, [esi + Point.x]
call printDec
; Print space
mov ecx, space
mov edx, 1
call printString
; Print y value
mov eax, [esi + Point.y]
call printDec
; Print newline
call printNewLine
; Restore the value of esi
pop esi
; Increment to the next structure
add esi, Point.size
dec ebx
jnz print_loop
jmp code_exit
code_exit:
; Exit the program
mov eax, 1
xor ebx, ebx
int 0x80
readInt:
; Save register values of the called function
pusha
; Allocate buffer for input
sub esp, 16
; Read input from the user (system call 3)
mov eax, 3
xor ebx, ebx
lea ecx, [esp]
mov edx, 15
int 0x80
; Convert string to integer
xor eax, eax
xor edi, edi
lea edi, [esp]
.str_to_int_loop:
cmp byte [edi], 10 ; Check for newline character
je .str_to_int_done
; Multiply eax by 10
lea ecx, [eax * 2 + eax] ; ecx = eax * 3
lea eax, [ecx * 2 + ecx] ; eax = ecx * 3 + ecx = eax * 9
; Subtract ASCII '0'
sub byte [edi], '0'
add al, byte [edi]
inc edi
jmp .str_to_int_loop
.str_to_int_done:
; Restore stack and register values
add esp, 16
popa
ret
printString:
;Save register values of called function
pusha
mov eax, 4 ;use 'write' system call = 4
mov ebx, 1 ;file descriptor 1 = STDOUT
int 80h ;call the kernel
;restore the old register values of the called function
popa
ret
; Add printNewLine function
section .data
nl db "", 10
section .text
printNewLine:
;save register values of the called function
pusha
mov ecx, nl
mov edx, 1
mov eax, 4
mov ebx, 1
int 0x80
;restore the old register values of the called function
popa
ret
printDec:
section .bss
decstr resb 10;
ct1 resd 1
section .text
pusha ;save all registers
; Save the value of edi
push edi
mov dword[ct1], 0 ; assume initially 0
mov edi, decstr ;edi points to dec-string in memory
add edi, 9 ;moved to the last element of string
xor edx, edx
whileNotZero:
mov ebx, 10 ;get ready to divide by 10
div ebx ;divide by 10
add edx,'0' ; convert to ascii char
mov byte[edi], dl ; put it in string
dec edi ;move to next char in string
inc dword[ct1]
xor edx, edx ;clear edx
cmp eax, 0 ;is remainder 0
jne whileNotZero ; keep looping
; Restore the value of edi
pop edi
inc edi ; conversion finish
mov ecx, edi
mov edx, [ct1]
mov eax, 4
mov ebx, 1
int 0x80
popa ;restore registers
ret
已尝试使用ALIGN,已检查以确保存储正确。
1条答案
按热度按时间kkbh8khc1#
代码中的问题列表
多余的第二个附加物。要删除。
这两个跳跃都是多余的。
未给出所需的EDX参数。
一个多余的跳转,但罚款的情况下,未来增加的程序。
你少了1倍!乘以10是简单的
imul eax, 10
。进位需要在整个EAX中传播。
你可以写
movzx edx, byte [edi]
sub edx, '0'
add eax, edx
。由于
pusha
...popa
,readInt 不会返回EAX寄存器中的任何内容。在 printDec 中,单独保存EDI不仅是多余的,而且是有害的。要删除。