x64位汇编

2023-12-09

我不久前开始汇编(nasm)编程。现在我用汇编实现创建了一个 C 函数,它打印一个整数。我使用扩展寄存器让它工作,但是当我想用 x64 寄存器(rax、rbx、..)写入它时,我的实现失败了。你们有人看到我错过了什么吗?

main.c:

#include <stdio.h>

extern void printnum(int i);

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

        return 0;
}

32位版本:

; 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 版本:

; 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 位模式下使用 32 位调用约定。如果您从 C 调用这些汇编例程,则不会成功。64 位调用约定记录如下:http://www.x86-64.org/documentation/abi.pdf

另外,不要开放代码系统调用。调用 C 库中的包装器。那样errno设置正确后,您可以利用sysenter/syscall,您不必处理正常调用约定和系统调用参数约定之间的差异,并且可以避免某些低级 ABI 问题。 (你的另一个问题是write对于 Linux/x86-64,是系统调用号 1,而不是 4。)

社论旁白:如今在汇编中编写任何内容有两个,也只有两个原因:

  1. 你正在写下仅存的极少数深奥魔法之一cannot单独用 C 语言编写(一个很好的例子是libffi)
  2. 您正在手动优化一个已被优化的内循环子例程measured性能至关重要,而 C 编译器在这方面做得不够好。

否则就用 C 写什么就行了。你的继任者会感谢你的。

EDIT:检查系统调用号码。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

x64位汇编 的相关文章

随机推荐

  • Ansible:使用带变量的嵌套组

    我遇到的情况是 我们有 3 层盒子 在每一层中我们应用不同的变量设置 例如缓存目录所在的位置 但有很多默认值 我还需要重写per node基础 这通常是通过主机本身的库存变量来完成的 我不确定组织主办方的最佳方式是什么 以便优先作品对我有利
  • 为什么 hsync() 不刷新我的 hdfs 文件?

    尽管有关于这个主题的所有资源 但我在刷新磁盘上的 hdfs 文件时遇到问题 hadoop 2 6 呼唤FSDataOutputStream hsync 应该可以解决这个问题 但实际上它只有效一次 原因不明 这是一个失败的简单单元测试 Tes
  • 测试自定义 UITableViewCell、cellForRowAtIndexPath 因 nil 出口而崩溃

    我有一个包含 tableView 的 ViewController 由于我需要用测试很好地覆盖代码 因此我需要为 tableView cellForRowAtIndexPath 编写一个测试 import UIKit class MainV
  • vbscript:如何将日期转换为天和时间

    我从 WMI 获得了上次启动时间 它看起来为 20141103113859 220250 060 我想将其转换为当前时间的天数和时间 是否可以 来自帮助 使用 SWbemDateTime 对象将它们转换为常规日期和时间 Windows 20
  • TabActivity 中永远不会调用 onActivityResult

    我知道有很多相同的问题 但 OnActivityResult 仍然没有被调用 这是我的代码 活动一 Intent i new Intent Bundle b new Bundle b putString ActivityB LINK ad
  • WPF 甜甜圈进度条

    我正在尝试将 WPF 4 Unleashed 一书中找到的饼图 ProgressBar 调整为看起来像甜甜圈 我觉得我已经成功了一半 但我不知道如何解决最后一个问题 这是一张图片 说明了我想要的以及我已经实现的目标 这就是我想要的样子 使用
  • 如何强制 C# 构建过程包含代码中未使用的程序集

    我有一个名为 Company Application 的应用程序 它确实使用库 公司 控制反转 公司 职能 合同 公司 职能 该应用程序使用 InversionOfControl 来侦察程序集部分应用程序域 方法是 appDomain Ge
  • 在表单加载上使用进度条

    我正在尝试用 C 设计一个 WinForms 控件 它将在加载时从数据库中获取一些数据 我想用进度条来显示进度 我尝试了这段代码 以及许多其他代码 protected override void OnLoad EventArgs e bas
  • Django 中的“gettext()”与“gettext_lazy()”

    我有一个关于使用 ugettext 的问题gettext lazy 用于翻译 我了解到在模型中我应该使用gettext lazy 而在视图 ugettext 中 但是还有其他地方我应该使用吗gettext lazy 也 表单定义又如何呢 它
  • 给定两个整数列表,我们如何找到一个列表中与另一个列表中最接近的数字? [关闭]

    Closed 这个问题需要多问focused 目前不接受答案 鉴于我有两个不同的整数列表 a 1 4 11 20 25 and b 3 10 20 我想返回一个长度列表len b 存储最接近的数字a对于每个整数b 所以 这应该返回 4 11
  • Outlook 加载项崩溃或您的服务器管理员限制了您可以同时打开的项目数量

    我创建了一个简单的 Outlook 插件 用于将联系人从一个文件夹复制到另一个文件夹 约 5000 个联系人 为什么我需要这个 有一种奇怪的方法可以创建如上所述的公共地址簿here 那么为什么不复制公用文件夹中的所有联系人呢 我希望我的团队
  • 六边形联合图的 Seaborn 成对矩阵

    我正在尝试生成比较分布的成对图矩阵 像这样的东西 由于我有很多点 我想使用十六进制图来减少时间和绘图复杂性 import seaborn as sns import matplotlib pyplot as plt tips sns loa
  • 如何在制作 htmlhelp 时使用 Sphinx RTD 主题隐藏侧边栏

    使用时是否可以隐藏侧边栏Sphinx与ReadTheDocs theme 再扩展一下问题 我可以在发出命令时包含侧边栏吗 制作 html 并且不包括它发出命令 制作 htmlhelp 不改变代码 也许在layout html 中添加一些东西
  • JodaTime - 我如何知道指定时间段内是否发生夏令时?

    我需要知道该期间是否由以下定义 DateTime start DateTime end 里面有夏令时 我正在迭代由 start end 定义的周期集合 并在每次迭代中将开始和结束时间向前移动 24 小时 生成的周期从午夜开始 到下一个午夜之
  • 以编程方式将目标添加到按钮会引发错误“无法识别的选择器发送到类”

    不知道为什么当我尝试使用我在代码中创建的按钮时收到 无法识别的选择器发送到类 错误 这是我的代码 let sendButton UIButton let button UIButton type system button setTitle
  • 使用sparkr时我应该在工作节点上预安装cran r包吗

    我想在 cran 上使用 r 包 例如forecast等与sparkr并遇到以下两个问题 我应该在工作节点上预安装所有这些软件包吗 但是当我读spark的源码时这个文件 似乎spark会自动压缩包并通过 jars或 packages将它们分
  • 无法在 Swift 中替换字符串

    尝试转义字符串的一些特殊字符以通过 xml api 发送它 尝试了下面的代码 但不适用于所有出现的单引号 和双引号 var strToReturn Hello world strToReturn strToReturn replacingO
  • clicklistener 和 longclicklistener 在同一个按钮上?

    我正在创建一个呼叫 拨号按钮 当我单击该呼叫 拨号按钮时 将根据编辑文本中显示的输入进行呼叫 我设法完成了那部分 你们能告诉我是否可以在同一个呼叫 拨号按钮上单击更长的时间 以便可以出现一个吐司来要求用户选择其他内容 我对 setOnLon
  • 使用 netbeans 支持的新 git 用户无法从远程存储库提取最新提交

    我是一个新的 GIT 用户 使用 win7 上内置的 NetBeans 支持 我在另一台计算机上对项目文件进行了一些更改 并将它们提交到远程存储库 当我尝试从远程存储库中提取最新版本时 出现以下错误 IDE Nov 13 2012 11 3
  • x64位汇编

    我不久前开始汇编 nasm 编程 现在我用汇编实现创建了一个 C 函数 它打印一个整数 我使用扩展寄存器让它工作 但是当我想用 x64 寄存器 rax rbx 写入它时 我的实现失败了 你们有人看到我错过了什么吗 main c includ