我看过类似的问题,但似乎找不到我的代码有什么问题。
我正在尝试在 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 进行编译。
我有一个简单的程序,它的核心是一个浮动的二维数组,据说代表气体浓度,我一直试图想出一个简单的算法,模拟向外扩展的气体,如云,最终结束整个电网中的气体浓度相同.
例如,给定的状态进展可以是:(为简单起见,使用整数)
起始状态
00000
00000
00900
00000
00000
1次通过算法后的状态
00000
01110
01110
01110
00000
另外一个pas应该给5x5网格都包含值0.36(9/25).
我已经在纸上试过了,但无论我如何尝试,我都无法绕过算法来做到这一点.
所以我的问题是,我该如何着手尝试编写这种算法?我尝试了一些东西,应用卷积,试图依次取出每个网格单元并将其分发给邻居,但它们最终都会产生不良影响,例如最终以比我最初开始时更少的气体结束,或者所有气体运动都在一个方向,而不是从中心向外扩展.我真的无法理解它并且会感激任何帮助.
我正在学习asm,这是我的(很多)问题之一:我想改变一些数组索引的值.让我们说:
我试过movl %eax, (-4(%ebp),0(%esp),4)但是没用.更糟糕的是,它会抛出语法错误:bobi.s:15:错误:垃圾邮件`(%ebp),0(%esp),4)'表达式后
什么是正确的语法?
在一个为Microsoft x64汇编器编写的简单程序中,我想在SSE寄存器(例如xmm0)和通用寄存器(例如rcx)之间移动64位值,如<MASM中的Intel语法>:
mov xmm0, rcx
...
mov rcx, xmm0
Run Code Online (Sandbox Code Playgroud)
这两行分别从生成以下错误消息ml64.exe:
但是,显然有可能在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中完成此操作?
我想编写一个DOS程序(我的第一个程序),我有点没有经验。
对于该程序,我需要超过64 KB的(传统)内存。如何获得额外的内存?理想情况下,我想为程序增加两个64k的内存块。我可以开始将数据写入地址空间中的某个地方还是需要请求额外的内存吗?
我对如何在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) 我正在尝试一个简单的汇编代码:
.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时保留这些名称信息?谢谢!
我试图理解英特尔语法和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)
他们为什么不同?
我想写一个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) 所以我想在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语法足够稳定.