How safe is this swap w/o pushing registers?

这一生的挚爱 提交于 2021-02-08 15:18:30

问题


I'm very new to Assembly and the code below is supposed to swap two integers via two different functions: first using swap_c and then using swap_asm.

However, I doubt, whether I need to push (I mean save) each value of registers before assembly code and pop them later (just before returning to main). In other words, will the CPU get mad at me if I return different register content (not the crucial ones like ebp or esp; but, just eax, ebx, ecx & edx) after running swap_asm function? Is it better to uncomment the lines in the assembly part?

This code runs OK for me and I managed to reduce the 27 lines of assembled C code down to 7 Assembly lines.

p.s.: System is Windows 10, VS-2013 Express.

main.c part

#include <stdio.h>

extern void swap_asm(int *x, int *y);

void swap_c(int *a, int *b) {
    int t = *a;
    *a = *b;
    *b = t;
}

int main(int argc, char *argv[]) {
    int x = 3, y = 5;
    printf("before swap    => x = %d     y = %d\n\n", x, y);

    swap_c(&x, &y);
    printf("after swap_c   => x = %d     y = %d\n\n", x, y);

    swap_asm(&x, &y);
    printf("after swap_asm => x = %d     y = %d\n\n", x, y);

    getchar();
    return (0);
}

assembly.asm part

 .686
.model flat, c
.stack 100h
.data

.code
swap_asm proc
    ; push eax
    ; push ebx
    ; push ecx
    ; push edx
    mov eax, [esp] + 4  ; get address of "x" stored in stack into eax
    mov ebx, [esp] + 8  ; get address of "y" stored in stack into ebx
    mov ecx, [eax]      ; get value of "x" from address stored in [eax] into ecx
    mov edx, [ebx]      ; get value of "y" from address stored in [ebx] into edx
    mov [eax], edx      ; store value in edx into address stored in [eax]
    mov [ebx], ecx      ; store value in ecx into address stored in [ebx]
    ; pop edx
    ; pop ecx
    ; pop ebx
    ; pop eax
    ret
swap_asm endp
end

回答1:


Generally, this depends on the calling convention of the system you are working on. The calling convention specifies how to call functions. Generally, it says where to put the arguments and what registers must be preserved by the called function.

On i386 Windows with the cdecl calling convention (which is the one you probably use), you can freely overwrite the eax, ecx, and edx registers. The ebx register must be preserved. While your code appears to work, it mysteriously fails when a function starts to depend on ebx being preserved, so better save and restore it.



来源:https://stackoverflow.com/questions/35397944/how-safe-is-this-swap-w-o-pushing-registers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!