跳后怎么回到主?

时间:2014-03-12 04:25:27

标签: assembly x86 nasm

好吧,我有这段代码:

SECTION .data
    message: db "Value = %d", 10, 0
    message2: db "End", 10, 0
SECTION .bss

SECTION .text

extern printf
global main

main:
    push ebp
    mov ebp, esp

    mov ebx, 0
    jmp loop
    push message2
    call printf
    mov esp, ebp
    pop ebp
    ret

loop: 
    push ebx 
    push message 
    call printf 
    inc ebx 
    cmp ebx, 100000
    jne loop 
    mov esp, ebp
    pop ebp

我想知道如何返回main然后打印message2?

感谢您的帮助和对不起我的英语。

3 个答案:

答案 0 :(得分:1)

问题是你正在调用使用cdecl调用约定的C函数(调用者必须清理堆栈)。这意味着在调用之后,必须将参数的大小(以字节为单位)添加到stackpointer。您的第一个printf需要2个双字参数(8个字节),因此您必须在调用后向stackpointer添加8。你的第二个调用传递一个dword,所以你将4添加到stackpointer。

这应该有效:

SECTION .data
        message: db "Value = %d", 10, 0
        message2: db "End", 10, 0
SECTION .bss

SECTION .text

extern printf
global main

main:
        push ebp
        mov ebp, esp

        mov ebx, 0
        call loop
        push message2
        call printf
        add esp, 4
        mov esp, ebp
        pop ebp
        ret

loop:
        push ebx
        push message
        call printf
        add esp, 8
        inc ebx
        cmp ebx, 10000
        jne loop
        ret

答案 1 :(得分:0)

以这种方式尝试:

SECTION .data

message: db "Value = %d", 10, 0

message2: db "End", 10, 0

SECTION .bss

SECTION .text

extern printf 全球主要

主:

push ebp
mov ebp, esp

mov ebx, 0
call loop

push message2
call printf

mov esp, ebp
pop ebp
ret

循环:

push ebx
push message
call printf 
inc ebx 
cmp ebx, 100000
jne loop 

ret

答案 2 :(得分:0)

可能没有足够的排名作为评论添加......

在jmp之前推送返回地址

看到这个: Substitutes for x86 assembly 'call' instruction?