64位汇编 [英] x64 bit assembly

查看:249
本文介绍了64位汇编的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始组装(NASM)编程不是很久以前。现在我用它打印一个整数集实现C函数。我得到它的工作使用扩展寄存器,但是当我要与64位寄存器写入(RAX,RBX,..)我执行失败。是否有任何的你看到了什么我错过了吗?

I started assembly (nasm) programming not too long ago. Now I made a C function with assembly implementation which prints an integer. I got it working using the extended registers, but when I want to write it with the x64 registers (rax, rbx, ..) my implementation fails. Does any of you see what I missed?

的main.c:

#include <stdio.h>

extern void printnum(int i);

int main(void)
{
        printnum(8);
        printnum(256);

        return 0;
}

32位版本:

32 bit version:

; main.c: http://pastebin.com/f6wEvwTq
; nasm -f elf32 -o printnum.o printnum.asm
; gcc -o printnum printnum.o main.c -m32

section .data
    _nl db 0x0A
    nlLen equ $ - _nl

section .text
    global printnum


printnum:
        enter 0,0

        mov eax, [ebp+8]

        xor ebx, ebx
        xor ecx, ecx
        xor edx, edx
        push ebx
        mov ebx, 10

startLoop:

        idiv ebx
        add edx, 0x30

        push dx ; With an odd number of digits this will screw up the stack, but that's ok
                ; because we'll reset the stack at the end of this function anyway.
                ; Needs fixing though.
        inc ecx
        xor edx, edx

        cmp eax, 0
        jne startLoop

        push ecx
        imul ecx, 2

        mov edx, ecx

        mov eax, 4 ; Prints the string (from stack) to screen
        mov ebx, 1
        mov ecx, esp
        add ecx, 4
        int 80h

        mov eax, 4 ; Prints a new line
        mov ebx, 1
        mov ecx, _nl
        mov edx, nlLen
        int 80h

        pop eax ; returns the ammount of used characters

        leave
        ret

64版:

; main.c : http://pastebin.com/f6wEvwTq
; nasm -f elf64 -o object/printnum.o printnum.asm
; gcc -o bin/printnum object/printnum.o main.c -m64

section .data
    _nl db 0x0A
    nlLen equ $ - _nl

section .text
    global printnum

printnum:
    enter 0, 0

    mov rax, [rbp + 8]  ; Get the function args from the stac
    xor rbx, rbx
    xor rcx, rcx
    xor rdx, rdx

    push rbx        ; The 0 byte of the string
    mov rbx, 10     ; Dividor

startLoop:
    idiv rbx        ; modulo is in rdx
    add rdx, 0x30

    push dx

    inc rcx         ; increase the loop variable
    xor rdx, rdx        ; resetting the modulo

    cmp rax, 0
    jne startLoop

    push rcx        ; push the counter on the stack
    imul rcx, 2

    mov rdx, rcx        ; string length

    mov rax, 4
    mov rbx, 1
    mov rcx, rsp        ; the string
    add rcx, 4
    int 0x80

    mov rax, 4
    mov rbx, 1
    mov rcx, _nl
    mov rdx, nlLen
    int 0x80

    pop rax
    leave

    ret         ; return to the C routine

在此先感谢!

推荐答案

我不知道,如果这个答案是与你看到的(因为你没有指定有关失败是什么东西)的问题,但64位code比32位code做了不同的调用约定。这两个主要的64位Intel的ABI(Windows和放大器;的Linux / BSD / Mac OS)中的寄存器而不是在栈上传递函数参数。你的程序似乎仍然可以期待他们的堆栈,这是不正常的方式去了解它。

I'm not sure if this answer is related to the problem you're seeing (since you didn't specify anything about what the failure is), but 64-bit code has a different calling convention than 32-bit code does. Both of the major 64-bit Intel ABIs (Windows & Linux/BSD/Mac OS) pass function parameters in registers and not on the stack. Your program appears to still be expecting them on the stack, which isn't the normal way to go about it.

编辑:现在,我看到有一个C 的main()程序调用的函数,我的回答是的完全的有关问题,你再有。

Now that I see there is a C main() routine that calls your functions, my answer is exactly about the problem you're having.

这篇关于64位汇编的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆