我正在尝试学习汇编,并有一个AT&T语法的程序,用于GNU AS,我认为应该可行.我收到GDB的错误:
Program received signal SIGSEGV, Segmentation fault.
.PROGRAM () at concatenator.s:60
60 call strlen
Current language: auto; currently asm
Run Code Online (Sandbox Code Playgroud)
代码是:
.file "concatenator.s"
.globl _start
.section .text
strlen:
mov %esp, (str1)
push %ebx
push %ecx
push %edx
mov $1, %edi
sub %ecx, %ecx
sub %al, %al
not %ecx
cld
repne scasb
not %ecx
dec %ecx
mov %ecx, %eax
pop %edx
pop %ecx
pop %ebx
leave
ret
write:
push %eax
push %ebx
push %ecx
push %edx
mov %eax, %ecx
mov $4, …Run Code Online (Sandbox Code Playgroud) 我是汇编级编码的新手,所以我对.align的做法感到有些困惑.我已经查看了很多地方的功能.https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ok05.html在此链接中,.align的说明在页面右侧的红色框中给出.我评论的另一个地方是http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0489c/Babecdje.html.地址是4字节对齐还是8字节对齐是什么意思?
如果我在我的代码中使用以下说明
.align 4
pattern:
Run Code Online (Sandbox Code Playgroud)
然后意味着分配给模式的地址将是4*n或16*n(2 ^ 4 = 16)的形式.
在64位linux上学习GAS汇编.许多教程都是针对32位汇编的.
很难通过x86_64程序集进行丛林攻击.
当我用gcc编译ac程序时,我仍然看到一些%eax和movl.
我主要玩int32_t.
但我认为必须使用64位指令x86_64(如rax,rbx等等).
我不太了解.他们不应该%rax和movq?在我的装配程序中,我应该使用movq,对吧?即使是32位整数?我是一个迷失的初学者.
谢谢
例如,我想写一些类似的东西,'a'而不是0x61像我在C语言中那样。
该手册在以下位置提到了它们:https : //sourceware.org/binutils/docs/as/Chars.html,但如果没有示例,我不确定我是否理解。
我有大量的常量,这些常量被越来越多的源文件使用.我需要能够玩它的价值,所以在一个地方定义它很方便.
我的情况的一个例子如下:
我定义变量的头文件rmode_loc.h:
#define __ASSEMBLER__
#define BSEQ_HI 0xF000
#define BSEQ_LO 0x0000
Run Code Online (Sandbox Code Playgroud)
我们(应该)使用的一些代码的摘录,myprog.S:
.code16
/* Include constants */
#include "rmode_loc.h"
_start:
...
push $BSEQ_HI
...
mov $BSEQ_LO, %bx
Run Code Online (Sandbox Code Playgroud)
但是,在尝试编译时,链接器会报告以下错误:
myprog.o: In function `_start':
(.text+0x1b): undefined reference to `BSEQ_HI'
myprog.o: In function `_start':
(.text+0x1f): undefined reference to `BSEQ_LO'
Run Code Online (Sandbox Code Playgroud)
显然正在尝试链接这些"符号" - 因此我得出结论,预处理器没有将符号替换为值所表示的值rmode_loc.h.
我读了另一个SO帖子(找不到链接),其中提到如果源文件的扩展名.s没有预处理会发生,并且__ASSEMBLER__还给出了定义的建议- 但是,这似乎不是在这里发布,因为所有的源都有.S扩展,我#define __ASSEMBLY__在标题中添加了一个.
然而,使用GCC作为前端进行编译时,即gcc myprog.S -o myprog,将BSEQ标签正确更换,一切编译.
我的问题是,在使用as而不是gcc产生这些结果时,预处理有什么区别,在使用gcc编译汇编代码时是否有任何重大的技术差异as?
我有一些代码可以旋转我的数据.我知道GAS语法有一个可以旋转整个字节的汇编指令.但是,当我尝试遵循C++中循环移位(旋转)操作的最佳实践的任何建议时,我的C代码编译成至少5条指令,这些指令使用了三个寄存器 - 即使在使用-O3进行编译时也是如此.也许那些是C++的最佳实践,而不是C?
在任何一种情况下,如何强制C使用ROR x86指令来旋转我的数据?
未编译到rotate指令的精确代码行是:
value = (((y & mask) << 1 ) | (y >> (size-1))) //rotate y right 1
^ (((z & mask) << n ) | (z >> (size-n))) // rotate z left by n
// size can be 64 or 32, depending on whether we are rotating a long or an int, and
// mask would be 0xff or 0xffffffff, accordingly
Run Code Online (Sandbox Code Playgroud)
我不介意使用__asm__ __volatile__旋转,如果这是我必须做的.但我不知道如何正确地做到这一点.
我正在使用 GAS 汇编器为 linux x86_64 编写一个 hello world 程序,这是我的 AT&T 语法代码。
#.intel_syntax noprefix
.section .data
msg:
.ascii "hello world\n"
.section .text
.globl _start
_start:
movq $1, %rax
movq $1, %rdi
movq $msg, %rsi
movq $12, %rdx
syscall
movq $60, %rax
movq $0, %rdi
syscall
Run Code Online (Sandbox Code Playgroud)
这有效并打印“hello world”。这是英特尔语法:
.intel_syntax noprefix
.section .data
msg:
.ascii "hello world\n"
.section .text
.globl _start
_start:
mov rax, 1
mov rdi, 1
mov rsi, msg
mov rdx, 12
syscall
mov rax, 60
mov rdi, 0
syscall
Run Code Online (Sandbox Code Playgroud)
这编译并运行良好,但不打印“hello …
我正在学习如何使用汇编语言(顺便说一句在Raspberry Pi上),并且想知道使用gcc和as进行编译之间有什么区别。
到目前为止,我注意到的差异是:
as。as似乎比单独识别要好gcc。gcc在使用整数除法之类的指令之前,我必须告诉架构。gcc我可以很方便地在C标准库函数。我认为可以使用,as但我还没有弄清楚。我想坚持使用特定的编译器。我应该知道还有什么其他区别。使用这两种方法都有优点/缺点吗?
以下是在 中定义变量的有效方法asm吗?
.globl main
.globl a, b, c, d
a: .byte 4
b: .value 7
c: .long 0x0C # 11
d: .quad 9
main:
mov $0, %eax
add a(%rip), %eax
add b(%rip), %eax
add c(%rip), %eax
add d(%rip), %eax
ret
Run Code Online (Sandbox Code Playgroud)
例如,是否需要/建议有一个.TEXT部分?究竟如何a(%rip)解析 的值$4?这对我来说几乎就像魔术一样。
我发现自己经常无法立即识别数字是十进制还是十六进制(如果十六进制数字没有前缀或字母)。例如,从上一个问题中得到一个喜欢0000000000400078但不确定是哪个的数字。
有没有办法在 x86_64 中明确指定带有前缀的十进制数?例如:
mov %rsp, %rbp
movb $0x16, -1(%rbp)
movb $0d22 -2(%rbp) # <-- something like this
movb $0b10110, -3(%rbp)
Run Code Online (Sandbox Code Playgroud)
我知道这样做movb $22, -2(%rbx)有效,但是有没有办法明确地为它加上前缀/后缀,以便我们知道它是小数?
assembly ×10
gnu-assembler ×10
x86 ×3
x86-64 ×3
att ×2
gcc ×2
64-bit ×1
arm ×1
c ×1
instructions ×1
intel-syntax ×1
raspberry-pi ×1
variables ×1