x64 位程序集 [英] x64 bit assembly
问题描述
我不久前开始汇编 (nasm) 编程.现在我制作了一个带有汇编实现的 C 函数,它打印一个整数.我使用扩展寄存器让它工作,但是当我想用 x64 寄存器(rax,rbx,..)编写它时,我的实现失败了.你们有没有看到我错过了什么?
main.c:
#include extern void printnum(int i);int main(void){打印编号(8);打印编号(256);返回0;}
32 位版本:
<代码>;main.c:http://pastebin.com/f6wEvwTq;nasm -f elf32 -o printnum.o printnum.asm;gcc -o printnum printnum.o main.c -m32.data 节_nl db 0x0AnlLen 等于 $ - _nl节.text全球印刷号码打印编号:输入 0,0mov eax, [ebp+8]异或 ebx, ebx异或 ecx, ecx异或edx, edx推 ebxmov ebx, 10开始循环:Idiv ebx添加edx,0x30推 dx ;对于奇数位数,这会搞砸堆栈,但没关系;因为无论如何我们都会在这个函数的末尾重置堆栈.;虽然需要修复.公司异或edx, edxcmp eax, 0jne 开始循环推ECXimul ecx, 2mov edx, ecx移动 eax, 4 ;将字符串(从堆栈中)打印到屏幕mov ebx, 1mov ecx, esp添加 ecx, 4整数 80 小时移动 eax, 4 ;打印一个新行mov ebx, 1mov ecx, _nlmov edx, nlLen整数 80 小时流行音乐;返回已使用字符的数量离开退
x64 版本:
<代码>;main.c:http://pastebin.com/f6wEvwTq;nasm -f elf64 -o 对象/printnum.o printnum.asm;gcc -o bin/printnum object/printnum.o main.c -m64.data 节_nl db 0x0AnlLen 等于 $ - _nl节.text全球印刷号码打印编号:输入 0, 0mov rax, [rbp + 8] ;从 stac 获取函数 args异或 rbx, rbx异或 rcx, rcx异或 rdx, rdx推 rbx ;字符串的 0 字节移动 rbx, 10 ;分频器开始循环:idiv rbx ;模在 rdx 中添加 rdx, 0x30推dx包括 rcx ;增加循环变量异或 rdx, rdx ;重置模数cmp rax, 0jne 开始循环推 rcx ;将计数器压入堆栈imul rcx, 2移动 rdx, rcx ;字符串长度mov rax, 4移动 rbx, 1mov rcx, rsp ;字符串添加 rcx, 4整数 0x80mov rax, 4移动 rbx, 1mov rcx, _nlmov rdx, nlLen整数 0x80流行音乐离开退;返回到 C 例程
提前致谢!
我不确定这个答案是否与您看到的问题有关(因为您没有指定任何有关失败的内容),但是64 位代码与 32 位代码具有不同的调用约定.两个主要的 64 位 Intel ABI(Windows 和 Linux/BSD/Mac OS)都在寄存器中而不是在堆栈中传递函数参数.您的程序似乎仍在堆栈中等待它们,这不是正常的处理方式.
现在我看到有一个 C main()
例程调用您的函数,我的回答是正是关于您遇到的问题.>
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 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
x64 version:
; 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
Thanks in advance!
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.
Edit: Now that I see there is a C main()
routine that calls your functions, my answer is exactly about the problem you're having.
这篇关于x64 位程序集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!