admin管理员组

文章数量:1122846

I am writing assembly code for my university course and it is not working at all. I have never written code like this before and I'm unsure what I am doing wrong. The code links to a few other codes for different things. Here is the code:

%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

After running a debugger I believe the segmentation fault is happening within the print_string function which is related to the manipulation of the stack and memory access.

Also "asm_io.inc" is this code below:

    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

I was given that code and also a code called asm_io.asm which has all of the definitions for the functions and also a c code file like the one below:

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

I am writing assembly code for my university course and it is not working at all. I have never written code like this before and I'm unsure what I am doing wrong. The code links to a few other codes for different things. Here is the code:

%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

After running a debugger I believe the segmentation fault is happening within the print_string function which is related to the manipulation of the stack and memory access.

Also "asm_io.inc" is this code below:

    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

I was given that code and also a code called asm_io.asm which has all of the definitions for the functions and also a c code file like the one below:

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
Share Improve this question edited Nov 24, 2024 at 16:49 Sep Roland 38.8k9 gold badges48 silver badges88 bronze badges asked Nov 21, 2024 at 15:53 Rhys EvansRhys Evans 111 silver badge1 bronze badge 1
  • What command line do you use to compile and link this code? What OS are you using? – Employed Russian Commented Nov 21, 2024 at 15:57
Add a comment  | 

1 Answer 1

Reset to default 3

You pushed the argument to the stack:

push name_prompt
call print_string

whereas print_string is looking for it inside EAX:

push    eax
push    dword string_format ; assuming a "%s" constant for printf
call    _printf

Suggested fix: pass the address of your string in EAX.


Also it seems to me that the function restores the stack after itself, so you should double-check that add esp, 4 is actually needed.

If there is an explanation on how the IO library you are using expects its arguments to be passed, you should look at it again.

本文标签: x86Assembly code not working need help finding the issueStack Overflow