标签: gnu-assembler

如何在 MacOS 上正确使用“write”系统调用打印到标准输出?

我看过类似的问题,但似乎找不到我的代码有什么问题。

我正在尝试在 MacOS 上进行“write”系统调用以将字符串打印到标准输出。

我能够printf完美地做到这一点,并且熟悉在 x64 汇编中调用其他函数。

然而,这是我第一次尝试syscall

我正在使用 GCC 的 GAS 汇编器。

这是我的代码:

.section __TEXT,__text

.globl _main

_main:
    pushq %rbp
    movq %rsp, %rbp

    subq $32, %rsp

    movq $0x20000004, %rax
    movq $1, %rdi
    leaq syscall_str(%rip), %rsi
    movq $25, %rdx
    syscall

    jc error

    xorq %rax, %rax

    leave
    ret

error:
    movq $1, %rax
    leave
    ret

.section __DATA,__data
syscall_str:
    .asciz "Printed with a syscall.\n"
Run Code Online (Sandbox Code Playgroud)

看起来没有任何错误;根本没有写入任何内容stdout

我知道它start通常用作 MacOS 上可执行文件的起点,但它不能使用 GCC 进行编译。

macos assembly x86-64 gnu-assembler system-calls

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

用于在2D网格上建立膨胀气体的算法

我有一个简单的程序,它的核心是一个浮动的二维数组,据说代表气体浓度,我一直试图想出一个简单的算法,模拟向外扩展的气体,如云,最终结束整个电网中的气体浓度相同.

例如,给定的状态进展可以是:(为简单起见,使用整数)

起始状态

00000
00000
00900
00000
00000

1次通过算法后的状态

00000
01110
01110
01110
00000

另外一个pas应该给5x5网格都包含值0.36(9/25).
我已经在纸上试过了,但无论我如何尝试,我都无法绕过算法来做到这一点.

所以我的问题是,我该如何着手尝试编写这种算法?我尝试了一些东西,应用卷积,试图依次取出每个网格单元并将其分发给邻居,但它们最终都会产生不良影响,例如最终以比我最初开始时更少的气体结束,或者所有气体运动都在一个方向,而不是从中心向外扩展.我真的无法理解它并且会感激任何帮助.

algorithm math gnu-assembler fluid expansion

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

asm中的内存寻址

我正在学习asm,这是我的(很多)问题之一:我想改变一些数组索引的值.让我们说:

  • %eax包含我的新值
  • 堆栈的顶部(即(0)%esp)包含数组的索引
  • -4(%ebp)包含数组的地址.

我试过movl %eax, (-4(%ebp),0(%esp),4)但是没用.更糟糕的是,它会抛出语法错误:bobi.s:15:错误:垃圾邮件`(%ebp),0(%esp),4)'表达式后

什么是正确的语法?

x86 assembly gnu-assembler

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

在xmm和ml64中的通用寄存器之间移动四字?

在一个为Microsoft x64汇编器编写的简单程序中,我想在SSE寄存器(例如xmm0)和通用寄存器(例如rcx)之间移动64位值,如<MASM中的Intel语法>:

mov xmm0, rcx
...
mov rcx, xmm0
Run Code Online (Sandbox Code Playgroud)

这两行分别从生成以下错误消息ml64.exe

  • 错误A2152:协处理器寄存器不能为第一个操作数
  • 错误A2070:无效的指令操作数

但是,显然有可能在x64中完成此简单任务。例如,以下是一个可运行的x64程序,我可以使用GCC <AT&T语法使用GCC 4.8.2>汇编并运行该程序:

.text
    .globl main
main:
    movl $1, %ecx
    movq %rcx, %xmm0
    movq %xmm0, %rax
    ret
Run Code Online (Sandbox Code Playgroud)

不出所料,该程序的返回值为1,其objdump输出为main()

1004010d0:   b9 01 00 00 00          mov    $0x1,%ecx
1004010d5:   66 48 0f 6e c1          movq   %rcx,%xmm0
1004010da:   66 48 0f 7e c0          movq   %xmm0,%rax
1004010df:   c3                      retq
Run Code Online (Sandbox Code Playgroud)

所以我的问题是,鉴于ml64.exe产生上述错误,我该如何在MASM中完成此操作?

64-bit assembly x86-64 masm gnu-assembler

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

如何在DOS中获得额外的段?

我想编写一个DOS程序(我的第一个程序),我有点没有经验。

对于该程序,我需要超过64 KB的(传统)内存。如何获得额外的内存?理想情况下,我想为程序增加两个64k的内存块。我可以开始将数据写入地址空间中的某个地方还是需要请求额外的内存吗?

assembly memory-management dos gnu-assembler x86-16

4
推荐指数
3
解决办法
1035
查看次数

如何实现汇编变量?

我对如何在Assembly中实现变量感到有点困惑.我知道以下声明在程序的data部分中创建了一个命名的内存位置:

.section .data
        var:
                .long 23
Run Code Online (Sandbox Code Playgroud)

然后您可以访问变量,例如:

movl var, %eax //read from var location
Run Code Online (Sandbox Code Playgroud)

我不清楚的是上面的说明是如何实际实现的.我的印象是,在使用之前,需要将内存引用(甚至是绝对内存引用)加载到寄存器中.

汇编程序是否需要将上述指令转换为多个指令,例如:

leal var, %ebx
movl (%ebx), %eax
Run Code Online (Sandbox Code Playgroud)

或者汇编程序是否跟踪var该位置的地址并访问该位置,就好像它是绝对的即时访问一样,例如:

movl ($addr_of_var), %eax
Run Code Online (Sandbox Code Playgroud)

x86 assembly gnu-assembler

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

无法在gdb中找到.bss部分中定义的变量名称

我正在尝试一个简单的汇编代码:

.section .data
output:
    .ascii "The processor Vendor ID is 'xxxxxxxxxxxx'\n"
.section .bss
    .lcomm buffer, 12
.section .text
.code32
.globl _start
_start:
    movl $0, %eax
    cpuid
    movl $output, %edi
Run Code Online (Sandbox Code Playgroud)

在.bss部分我定义了一个名为"buffer"的变量

当我尝试在gdb中获取其地址/值时,它只是打印:

(gdb) p $buffer
$1 = void

使用objdump,我发现该名称不在ELF文件中,那么如何在运行as和ld时保留这些名称信息?谢谢!

assembly gdb gnu-assembler elf debug-symbols

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

为什么mov eax,val不是英特尔语法相当于mov $ val,%eax?

我试图理解英特尔语法和AT&T语法之间的差异(我使用的是GNU).

我有两个文件,intel.s:

.intel_syntax noprefix

val:
    mov eax, val
Run Code Online (Sandbox Code Playgroud)

和atandt.s:

val:
    mov $val, %eax
Run Code Online (Sandbox Code Playgroud)

我正在尝试将AT&T版本转换为英特尔版本.但我得到了不同的结果:

$ objdump -d intel.o

intel.o:     file format elf32-i386


Disassembly of section .text:

00000000 <val>:
   0:   a1 00 00 00 00          mov    0x0,%eax
Run Code Online (Sandbox Code Playgroud)

$ objdump -d atandt.o

atandt.o:     file format elf32-i386


Disassembly of section .text:

00000000 <val>:
   0:   b8 00 00 00 00          mov    $0x0,%eax
Run Code Online (Sandbox Code Playgroud)

他们为什么不同?

x86 assembly gnu-assembler att

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

如果我尝试将其指向标签,为什么x86-assembly(r)中的寄存器会自动移入?

我想写一个bootloader,它只是打印"Hello World!" 在屏幕上,我不知道为什么我的字节混淆了.我正在尝试用AT&T语法编写它(请不要推荐英特尔语法)并尝试将本教程中的代码转换为AT&T语法.

现在这里是我的bootloader的相当短的代码:

start:
.code16         #real mode
.text
.org 0x0
.globl _main
_main:
    movw hello, %si
    movb $0x0e, %ah

loophere:
    lodsb
    or %al, %al     #is al==0 ?
    jz halt         #if previous instruction sets zero flag jump to halt
    int $0x10       #run bios interrupt 0x10 (ah is set to 0x0e so a character is displayed)
    jmp loophere


halt:
    cli
    hlt


hello:  .ascii "Hello world!\0"


filloop:    
    .fill (510-(.-_main)),1,0   #I hope this works. Fill bootloader with 0's until byte 510 …
Run Code Online (Sandbox Code Playgroud)

x86 assembly real-mode gnu-assembler bootloader

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

使用GAS AT&T指令计算引导扇区的填充长度?

所以我想在bootsector中添加填充.比方说,目前只有一个无限循环:jmp ..扇区需要512字节长.此外,0xaa55需要在最后添加的幻数.

jmp .
.skip 508, 0
.word 0xaa55
Run Code Online (Sandbox Code Playgroud)

但是,如果我想打印一些但不想将所有字节计算到适当大小的内容,该怎么办?
在Intel/NASM中,语法是:

; print something
times 510-($-$$) db 0
dw 0xaa55
Run Code Online (Sandbox Code Playgroud)

但在AT&T语法中呢?好了,循环(.rept)在这里不起作用,因为这里.不需要给出绝对值.我们和.skip/ 有同样的问题.space,他们也需要一个绝对值.

是否有使用某种循环/ .align/ .skip/ etc 添加填充的方法?

编辑:我as用来构建和链接,ld -Ttext 0x7c00 --oformat binary直到yasmAT&T语法足够稳定.

assembly gnu-assembler bootloader att x86-16

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