标签: yasm

汇编:为什么跳转到通过ret返回的标签会导致分段错误?

Linux程序集教程说明:

有一件非常重要的事情需要记住:如果您打算从程序返回(使用RET指令),请不要跳转到它!就像"从来没有!" 这样做会导致Linux上的分段错误(这是好的 - 所有程序都会终止),但在DOS中,它可能会因各种程度的可怕而在你脸上爆炸.

但我无法理解为什么它会导致分段错误.听起来就像从函数返回一样.

我有一种情况需要实现逻辑"如果X发生,请调用程序A.否则,调用程序B." 除了袋鼠编织意大利面条代码之外还有其他方式吗?

linux assembly nasm yasm

5
推荐指数
1
解决办法
1609
查看次数

代码对齐在组装中定时主循环的影响

假设我有以下主循环

.L2:
    vmulps          ymm1, ymm2, [rdi+rax]
    vaddps          ymm1, ymm1, [rsi+rax]
    vmovaps         [rdx+rax], ymm1
    add             rax, 32
    jne             .L2
Run Code Online (Sandbox Code Playgroud)

我想时间的方式是把它放在另一个像这样的长循环中

;align 32              
.L1:
    mov             rax, rcx
    neg             rax
align 32
.L2:
    vmulps          ymm1, ymm2, [rdi+rax]
    vaddps          ymm1, ymm1, [rsi+rax]
    vmovaps         [rdx+rax], ymm1
    add             rax, 32
    jne             .L2
    sub             r8d, 1                 ; r8 contains a large integer
    jnz             .L1
Run Code Online (Sandbox Code Playgroud)

我发现的是我选择的对齐方式会对时序产生重大影响(最高可达+ -10%).我不清楚如何选择代码对齐方式.我可以想到三个地方,我可能想要对齐代码

  1. 在函数入口处(参见triad_fma_asm_repeat下面的代码中)
  2. 在外循环的开始(.L1上面)重复我的主循环
  3. 在我的主循环开始时(.L2上图).

我发现的另一件事是,如果我在源文件中放入另一个例程,即更改一条指令(例如删除指令),即使它们是独立函数,也会对下一个函数的时序产生重大影响.我甚至在过去看到过影响另一个目标文件中的例程.

我在Agner Fog的优化装配手册中阅读了第11.5节"代码对齐",但我仍然不清楚调整代码以测试性能的最佳方法.他给出了一个例子,11.5,计时内循环,我并没有真正遵循.

目前,从我的代码中获得最高性能是一种猜测不同值和对齐位置的游戏.

我想知道是否有一种智能方法可以选择对齐方式?我应该对齐内圈和外圈吗?只是内循环?该功能的入口?使用短期或长期NOP是否重要?

我最感兴趣的是Haswell,其次是SNB/IVB,然后是Core2.


我尝试了NASM和YASM,并发现这是一个显着不同的领域.NASM仅插入一个字节的NOP指令,其中YASM插入多字节NOP.例如,通过将上面的内部和外部循环对齐到32字节,NASM插入20条NOP(0x90)指令,其中YASM插入以下内容(来自objdump)

  2c:   66 …
Run Code Online (Sandbox Code Playgroud)

x86 assembly nasm yasm

5
推荐指数
1
解决办法
576
查看次数

如何从汇编中调用C编写的代码?

已解决的问题 应使主符号全局化,以便链接器在链接时可以在目标文件中找到它.更正了代码.

在执行任务时,尝试从程序集中调用简单的C函数(YASM汇编程序):

写了C函数:

#include <stdio.h>

void
func_in_c(char *s)
{
        printf("%s", s);
}
Run Code Online (Sandbox Code Playgroud)

写了调用汇编代码:

        segment .data
str_t_c db "Wow", 0

        segment .text
        global  main ; That is the solution - let linker find global symbol
        extern printf
        extern func_in_c
main:
        push rbp
        mov rbp, rsp
        lea rdi, [str_to_c]
        call func_in_c
        leave
        ret
Run Code Online (Sandbox Code Playgroud)

汇编汇编:

yasm -f elf64 -m amd64 -g dwarf2 main.asm
Run Code Online (Sandbox Code Playgroud)

编译c代码:

gcc -o main_c.o -c main_c.c
Run Code Online (Sandbox Code Playgroud)

试图将两个目标文件链接到单个可执行二进制文件:

gcc -o main main_c.o main.o
Run Code Online (Sandbox Code Playgroud)

拿到:

...
In function _start:
(.text+0x20): undefined …
Run Code Online (Sandbox Code Playgroud)

c x86-64 yasm

5
推荐指数
1
解决办法
87
查看次数

Polygot包含nasm / yasm和C的文件

我想在C程序和要由nasm或yasm编译的程序集文件中包括很多魔术数字。

在纯C语言中,文件看起来像一系列定义,例如:

#define BLESS   55378008
#define ANSWER        42
...
Run Code Online (Sandbox Code Playgroud)

在nasm或yasm中,相同的include可以实现为:

%define BLESS   55378008
%define ANSWER        42
...
Run Code Online (Sandbox Code Playgroud)

唯一的不同是C和nasm 的define:前面的主角。#%

有什么办法可以编写一个polygot include,它可以让我将它同时包含在C和nasm中,并且只列出一次常量?

是的,我知道我可以使用sed或其他方法从另一个文件生成一个文件。

c x86 assembly nasm yasm

5
推荐指数
1
解决办法
356
查看次数

make:循环依赖关系丢失

我已经在stackoverflow和其他制作手册,网站上搜索了很长时间,但找不到任何尾随空格或错过make函数中的用法.你能帮我解决这个警告信息吗?

make: Circular main.asm.o <- main.asm dependency dropped.
Run Code Online (Sandbox Code Playgroud)

Makefile文件:

AS:=yasm
CC:=gcc
OUTPUTDIR:=$(shell pwd)/bin
ASFLAGS:=-g dwarf2 -f elf64 -a x86
CFLAGS:=-g

SOURCES=$(wildcard *.asm)
OBJECTS=$(patsubst %.asm,%.o,$(SOURCES))

%.o: $(SOURCES)
    $(AS) $(ASFLAGS) -o $(OUTPUTDIR)/$(OBJECTS) $<

all: $(OBJECTS)
    $(CC) $(CFLAGS) -o httpd $(OUTPUTDIR)/$(OBJECTS)

clean:
    rm $(OUTPUTDIR)/*
    rm httpd
Run Code Online (Sandbox Code Playgroud)

main.asm中:

section .text
  global main
  extern exit

main:
  mov rdi, 1
    call exit   
Run Code Online (Sandbox Code Playgroud)

谢谢 :)

assembly makefile yasm

4
推荐指数
1
解决办法
2万
查看次数

为什么在 NASM 中我们必须使用方括号 ([]) 来 MOV 到内存位置?

例如,如果我有一个名为 test 的变量,声明如下:

test db 0x01      ;suppose the address is 0x00000052
Run Code Online (Sandbox Code Playgroud)

如果我做这样的事情:

mov rax, test     ;rax = 0x00000052
mov rax, [test]   ;rax = 0x01
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试保存它时,如果我们遵循相同的模式:

mov test, 0x01    ;address 0x00000052 = 0x01
mov [test], 0x01  ;address 0x01 = 0x01
Run Code Online (Sandbox Code Playgroud)

但实际上是:

mov [test], 0x01  ;address 0x00000052 = 0x01
Run Code Online (Sandbox Code Playgroud)

那么,为什么方括号的行为取决于它们是第一个还是第二个操作数?

assembly nasm yasm

4
推荐指数
1
解决办法
938
查看次数

使用 YASM 构建 x264:未通过 ASM 检查

我的问题是,“我有新的 yasm,我认为 x264 应该很酷,为什么 x264 不酷?”

出于某些原因,我正在按照指南构建一个 CentOS docker 镜像(基于 centos:latest),其中包含一个从头开始构建的 ffmpeg 此处。这是一个很好的指南,它以前对我有用,所以我感觉很好。

今天我遇到了 libx264 构建点的瓶颈:具体来说,我说

PKG_CONFIG_PATH="/tmp/ffmpeg_build/lib/pkgconfig" \
  ./configure \
  --prefix="/tmp/ffmpeg_build" \
  --bindir="/tmp/bin" \
  --enable-static
Run Code Online (Sandbox Code Playgroud)

我得到回复

找不到汇编程序

最低版本为 nasm-2.13

如果你真的想在没有 asm 的情况下进行编译,请使用 --disable-asm 进行配置。

这是出乎意料的。我有 yasm,我理解它是 1) 在那里做 nasm 做的事情,但更好,2) 成为雏菊新鲜的最现代版本,因为我大约一个小时前从它的 repo 中取出它,并构建它五十九分钟前。就其价值而言,nasm 也在盒子上,因为说明要求它,但它低于其规定的版本(即“NASM 版本 2.10.07 编译于 2014 年 6 月 9 日”)

所以似乎没有找到 yasm 。还有另一个StackExchange question提到了这个问题,这是一个路径问题。因此,我将 yasm 添加到我的路径中,如下所示:

PATH=/tmp/ffmpeg_sources/yasm:$PATH \
  PKG_CONFIG_PATH="/tmp/ffmpeg_build/lib/pkgconfig" \
  ./configure
  ...etc
Run Code Online (Sandbox Code Playgroud)

这仍然会导致 Found-no-assembler 问题。作为最后一个令人困惑的方法,我明确地告诉脚本我想对变量 $AS 使用什么,因为根据我对 configure 的快速查看,这看起来像是 yasm/nasm 应该去的地方。命令变为:

AS=`which yasm`
  PKG_CONFIG_PATH="/tmp/ffmpeg_build/lib/pkgconfig" …
Run Code Online (Sandbox Code Playgroud)

linux ffmpeg x264 yasm

3
推荐指数
1
解决办法
3803
查看次数

yasm movsx、movsxd 操作数 2 的大小无效

我正在尝试使用 yasm 汇编下面的代码。我在 yasm 报告错误“错误:操作数 2 的大小无效”的地方添加了“此处”注释。为什么会发生这个错误?

segment .data
    a db 25
    b dw 0xffff
    c dd 3456
    d dq -14

segment .bss
    res resq 1

segment .text
    global _start

_start:
    movsx rax, [a] ; here
    movsx rbx, [b] ; here 
    movsxd rcx, [c] ; here
    mov rdx, [d]
    add rcx, rdx
    add rbx, rcx
    add rax, rbx
    mov [res], rax
    ret
Run Code Online (Sandbox Code Playgroud)

assembly x86-64 nasm yasm

3
推荐指数
1
解决办法
1986
查看次数

如何在装配中打印星形的三角形?

我需要获得以下输出:

*
**
***
****
*****
******
*******
********
*********
**********
Run Code Online (Sandbox Code Playgroud)

所以它的10行,而我的星星将从1开始到10。

目前我得到:

**********
***********
************
*************
**************
***************
****************
*****************
******************
*******************
********************
Run Code Online (Sandbox Code Playgroud)

我的代码:

*
**
***
****
*****
******
*******
********
*********
**********
Run Code Online (Sandbox Code Playgroud)

我尝试了又尝试了又尝试了,但是我无法获得所需的东西。

由于所有这些push和,我似乎无法找到一种将行与星线分开的方法pop

老实说,我对此不太了解。有人告诉我,执行循环需要它们,但是我不确定为什么要在函数star中调用外部循环。

我找不到任何的组合pushpop奏效。我不断得到很多星,或者每行一颗星,或者只有一颗星。

我真的不知道要更改哪些位并保持不变。我能够获得所需的输出,但是输出从未停止增加。

我能够得到从10颗星开始下降到1颗星的输出,但是从来没有我想要的。

我究竟做错了什么?我该怎么办?

assembly x86-64 nasm yasm

3
推荐指数
1
解决办法
1856
查看次数

在 yasm 中,当目标为 32 位代码时,如何指定 16 位近 jmp?

我试图让 yasm 输出一个 16 位近相对 jmp。具体来说,它将是带有操作数大小覆盖前缀的 rel16/rel32 jmp 操作码。我知道jmp short labelwill 发出一个 8 位近相对 jmp,ajmp long label将发出一个 32 位近相对 jmp,但如何让它发出 16 位近相对 jmp?

具体来说我正在使用bits 32cpu i686

x86 assembly yasm

3
推荐指数
1
解决办法
632
查看次数

标签 统计

yasm ×10

assembly ×8

nasm ×6

x86 ×3

x86-64 ×3

c ×2

linux ×2

ffmpeg ×1

makefile ×1

x264 ×1