我刚刚开始处理 struct 点,这让我很困惑.

程序应该允许用户输入5个值,将其保存在 struct 点中,然后返回值是什么.

"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



已try 使用ALIGN,已判断以确保其存储正确.

推荐答案

代码中的问题列表

; Debugging print statement
mov ecx, [esi + Point.x]
call printDec

printDec的论点在EAX指数中.这种误会发生了4次.

add esi, Point.size     ; Increment pointer to next structure in array
add esi, Point.size     ; Increment pointer to next structure in array

多余的第二次添加.将被移除.

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:

这两次 skip 都是多余的.

mov ecx, space
call printString

未提供所需的edX参数.

jmp code_exit
code_exit:

这是一次多余的 skip ,但在future 添加到程序中时可以很好地进行.

; Multiply eax by 10
lea ecx, [eax * 2 + eax] ; ecx = eax * 3
lea eax, [ecx * 2 + ecx] ; eax = ecx * 3 + ecx = eax * 9

你在这里还差1分钟!乘以10是简单的imul eax, 10.

; Subtract ASCII '0'
sub byte [edi], '0'
add al, byte [edi]

The carry needs to propagate through the whole EAX.
You could write movzx edx, byte [edi] sub edx, '0' add eax, edx.


Because of 100 ... 101, readInt isn't returning anything in the EAX register.

.str_to_int_done:
    ; Restore stack and register values
    add  esp, 16
    mov  [esp+28], eax    ; Return EAX through overwriting pushad.EAX
    popa
    ret

; Save the value of edi
push edi
...
; Restore the value of edi
pop edi

printDec年代,EDI的单独保存不仅是多余的,而且是有害的.将被移除.

Linux相关问答推荐

在新环境中使用Unicode范围的sed表达式有问题

Linux-如何区分目录中名称相同但扩展名不同的所有文件

Ansible-删除两个注释之间的代码块(包括注释本身)

在正在运行的进程的输出周围添加自定义字符串

x64 NASM 汇编程序在程序开始时显示分段错误

X86 程序集 - struct 点 - 存储/返回不正确?

awk 打印除最后一列以外的所有内容 + 最后一列

如何计算文本的时差,如 YYYYMMDDHHMMSSXXX 格式,包括毫秒

将 Visual Studio C++ 项目迁移到 Linux 和 CMake

在android上使用lldb-server进行lldb调试?

是否可以在 XTerm 或 Konsole 中使 stdout 和 stderr 输出具有不同的 colored颜色 ?

如何在初始化脚本中以特定用户身份运行命令?

Bash 变量:是否区分大小写?

如何 grep 精确的文字字符串(无正则表达式)

如何从命令行打开 Ubuntu Linux 上的 AVD 管理器?

并行运行 shell 脚本

Docker Bash 提示不显示 colored颜色 输出

从线程内Forking 是否安全?

如何为 Git 命令设置自动完成功能?

Linux 守护进程