我正在为我的大学课程编写汇编代码,但它根本不起作用。我以前从未写过这样的代码,我不确定我做错了什么。该代码链接到一些用于不同事物的其他代码。这是代码:
%include "asm_io.inc"
section .data
name_prompt db "Enter your name: ", 0
count_prompt db "Enter the number of repetitions (50-100): ", 0
error_msg db "Error: Number must be between 50 and 100.", 10, 0
welcome_msg db "Welcome, ", 0
newline db 10, 0
section .bss
name resb 128 ; Allocate 128 bytes for the name
num_reps resd 1
section .text
global asm_main ; Declare the function to be used by the C code
extern print_string ; External declarations from asm_io.inc
extern read_char
extern read_int
extern print_nl
asm_main: ; Entry point for the C code
push ebp ; Save the base pointer (set up stack frame)
mov ebp, esp ; Move stack pointer into base pointer
; Prompt for name
push name_prompt
call print_string
add esp, 4 ; Properly clean up the stack after calling print_string
; Read the name character-by-character
lea eax, [name]
call read_char_loop
call print_nl
validate_reps:
; Prompt for number of repetitions
push count_prompt
call print_string
add esp, 4
; Read number of repetitions
call read_int
mov [num_reps], eax
; Validate repetitions (must be between 50 and 100)
cmp eax, 50
jl invalid_reps
cmp eax, 100
jg invalid_reps
; Print welcome message the number of times specified
mov ecx, [num_reps]
print_loop:
cmp ecx, 0
jle end_loop
push welcome_msg
call print_string
add esp, 4
lea eax, [name]
push eax
call print_string
add esp, 4
call print_nl
dec ecx
jmp print_loop
invalid_reps:
push error_msg
call print_string
add esp, 4
call print_nl
jmp validate_reps
end_loop:
; Exit program cleanly using the exit system call
mov eax, 1 ; SYS_exit
xor ebx, ebx ; Status code 0
int 0x80
read_char_loop:
lea edi, [name]
mov ecx, 128
read_next_char:
call read_char
cmp al, 10
je end_read_char
mov [edi], al
inc edi
loop read_next_char
end_read_char:
mov byte [edi], 0
ret
运行调试器后,我相信分段错误发生在print_string函数内,这与堆栈和内存访问的操作有关。
“asm_io.inc”也是下面的代码:
extern read_int, print_int, print_string
extern read_char, print_char, print_nl
extern sub_dump_regs, sub_dump_mem, sub_dump_math, sub_dump_stack
%macro dump_regs 1
push dword %1
call sub_dump_regs
%endmacro
;
; usage: dump_mem label, start-address, # paragraphs
%macro dump_mem 3
push dword %1
push dword %2
push dword %3
call sub_dump_mem
%endmacro
%macro dump_math 1
push dword %1
call sub_dump_math
%endmacro
%macro dump_stack 3
push dword %3
push dword %2
push dword %1
call sub_dump_stack
%endmacro
我得到了该代码以及名为 asm_io.asm 的代码,其中包含函数的所有定义以及如下所示的 C 代码文件:
int __attribute__((cdecl)) asm_main( void );
int main() {
int ret_status;
ret_status = asm_main();
return ret_status;
}
print_string:
enter 0,0
pusha
pushf
push eax
push dword string_format
call _printf
pop ecx
pop ecx
popf
popa
leave
ret
您将参数压入堆栈
push name_prompt
call print_string
而
print_string
正在里面寻找它eax
push eax
push dword string_format ; assuming a "%s" constant for printf
call _printf
建议修复:在 eax 中传递字符串的地址。
而且在我看来,该函数会在其自身之后恢复堆栈,因此您应该仔细检查是否确实需要
add esp, 4
。
如果有说明您正在使用的 IO 库如何期望其参数被传递,您应该再看一遍。