我希望能够在汇编程序文件中定义一个不包含 NUL 字符的任何名称的符号。我如何让 GNU 汇编器创建这样的符号?NASM 怎么样?玛斯姆?
编辑:我使用以下 Python 脚本进行测试(需要 Python 3.5.1+):
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import tempfile
import os.path
import subprocess
import ctypes
def main(symbolname, quoter):
join = os.path.join
with tempfile.TemporaryDirectory() as d:
as_file_name = join(d, 'test.s')
with open(as_file_name, 'w') as file_object:
assembler = '''\
\t.globl "{0}"
"{0}":
\tmov $0x0, %rdi # exit status
\tmov $231, %rax # __NR_exit_group
\tsyscall
'''.format(quoter(symbolname))
file_object.write(assembler)
objectname, sharedlib = join(d, 'test.o'), join(d, 'test.so')
subprocess.check_call(['as', '-o', objectname, as_file_name])
subprocess.check_call(['ld', objectname, '-shared', '-o', sharedlib]) …Run Code Online (Sandbox Code Playgroud) 据我所知,使用 objdump,使用 gas
.section .text
Run Code Online (Sandbox Code Playgroud)
和
.text
Run Code Online (Sandbox Code Playgroud)
是等价的。这是真的?
来自气体手册.section name:
使用该
.section指令将以下代码组装到名为name的节中。
来自气体手册.text小节:
告诉
as将以下语句组合到编号为subsection的文本小节的末尾,这是一个绝对表达式。如果第被省略,则使用分段数为零。
我的问题也适用于.data.
.data我正在尝试使用 GAS 语法创建一个汇编程序,该程序可以在 x86-64 arch 上以位置无关的方式访问其变量,并强制执行32 位arch 和 IS (%eip而不是%rip)。
无论我尝试什么寄存器,我得到的最好结果都是a Segmentation fault: 11,即使这是为了访问EIP,我根本不应该这样做,因此是SF。最好的结果,因为这至少告诉我一些东西,而不是“嗯,这不行”。
gcc我正在macOS 10.13.6 mid 2010 Intel Core 2 Duo 上编译该文件(这clang可能就是原因):
$ gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 9.1.0 (clang-902.0.39.2)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
Run Code Online (Sandbox Code Playgroud)
并将一些选项传递给链接器:
gcc -m32 -Wl,-fatal_warnings,-arch_errors_fatal,-warn_commons,-pie test.s
Run Code Online (Sandbox Code Playgroud)
ld:警告:PIE 已禁用。绝对寻址(可能是 -mdynamic-no-pic)在代码签名的 PIE 中不允许,但在 /whatever.../test-a07cf9.o 的 _main 中使用。要修复此警告,请勿使用 -mdynamic-no-pic 进行编译或使用 -Wl,-no_pie ld: fatal warning(s)induced error (-fatal_warnings) clang: error: linker command failed …
据我了解,idiv %ebx将除以edx:eax32 位(按顺序连接成 64 位值)ebx。
但是,当我尝试将0x00000000:0xfffffffb(0 和 -5)除以0xffffffff(-1)时,出现浮点异常。
有人可以解释为什么吗?我很困惑为什么会发生这种情况,因为我毕竟没有除以 0。
请注意,我知道我需要签署扩展edx:eax才能实现我想要的,即计算-5/-1。然而,即使没有符号扩展,下面的内容也不会导致 FPE。
我希望你们度过了愉快的一天。我有一个关于将程序集编译为.bin. 我正在尝试使用这篇文章来修复它,但即便如此,我还是得到了`relocated truncation to fit: 16 against '.text'。
bootReal.s :
#generate 16-bit code
.code16
#hint the assembler that here is the executable code located
.text
.globl _start;
#boot code entry
_start:
jmp _boot #jump to boot code
welcome: .asciz "Hello, World\n\r" #here we define the string
.macro mWriteString str #macro which calls a function to print a string
leaw \str, %si
call .writeStringIn
.endm
#function to print the string
.writeStringIn:
lodsb
orb %al, %al
jz .writeStringOut …Run Code Online (Sandbox Code Playgroud) 我正在尝试将 xv6 引导代码从 At&t 语法转换为 Intel 语法,但我在使用 ljmp 指令时遇到了问题。我正在尝试学习 Intel 计算机的启动过程,并且我对 Intel 程序集不是特别擅长。
原始的 AT&T 语法是ljmp $0x8, $start32.
最小的例子:
.code16
jmp 0x8:start32 # won't assemble
.code32
start32:
nop
Run Code Online (Sandbox Code Playgroud)
使用as -32 -msyntax=intel -mnaked-reg foo.s和GNU Binutils的2.35.1产生
Error: junk ':start32' after expression的远JMP线。
我使用 GNU as 和 gcc 工具。
程序集也可能存在其他问题,例如 gdtdesc 和 gdt。
移植到英特尔语法的完整代码是:
# Start the first CPU: switch to 32-bit protectied mode, jump into C.
# The BIOS loads this code from the first sector of the …Run Code Online (Sandbox Code Playgroud) 像下面这样的事情可能吗?
cmp $3, %rdi
jz (%r11)
Run Code Online (Sandbox Code Playgroud)
file.s:52: 错误:`jz' 的操作数类型不匹配
或者:
警告:不带 `*' 的间接 jmp
或者您是否必须“跳过”一个标签,然后才能执行jmp %r11. 或者它是如何工作的?
似乎这里至少发生了一些事情,但其中之一是:
jmp %r11为jmp *%r11(为什么?),否则发出警告目前我正在做的是回旋处:
cmp $3, %rdi
jz fast_ret
fast_ret:
jmp *%r11
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 devkitpro 创建匹配的 GBA 反汇编,但我在使用 THUMB 指令时遇到了问题LDR R1, =0x3FF。
我希望它放在0x3FF文字池中并生成一个相对于 PC 的地址,这是汇编版本所做的,但是它坚持创建一个MOVW32 位指令。
我尝试使用长度说明符LDR.N强制它生成 16 位指令,但这似乎没有任何区别。
虽然我可以直接使用相对于 PC 的地址,但由于这是在文字池的中间,这将导致我不得不删除大量的池并以相同的方式实现加载,这将非常混乱,所以这只是最后的手段。如果有人知道某种方式,我可以强制此指令生成一个与 PC 相关的地址,这将非常有帮助。谢谢!
问题是我不能强迫gnu as将其解释jmp为shortor near,它不断地将其解释为far。
例如,以下代码会导致segfault:
int main() {
asm volatile (
// ".intel_syntax noprefix\n\t"
// "jmp lbl%=\n\t"
// "lbl%=:\n\t"
"jmp *lbl%=(%%rip)\n\t"
"lbl%=:\n\t"
// ".att_syntax\n\t"
: : : );
return 0;
}
Run Code Online (Sandbox Code Playgroud)
切换到注释的.intel_syntax变体,它工作得很好。
唯一的区别是
jmp lbl%=变成inteleb 00
尽管
jmp *lbl%=(%%rip)变成attff 25 00 00 00 00
.att_syntax如果将其解释为 ,如何强制它short jump?
在我的16位程序中,GAS拒绝执行以下指令:
movw %ip, %dx
Run Code Online (Sandbox Code Playgroud)
我发现这很奇怪,因为移动段寄存器可以正常工作,例如:
movw %ss, %ax
Run Code Online (Sandbox Code Playgroud)
完整的错误消息是:
错误:错误的寄存器名称`%ip'
我的版本字符串是:
GNU汇编器(GNU Binutils)2.22
gnu-assembler ×10
assembly ×9
att ×4
x86 ×4
x86-16 ×2
x86-64 ×2
arm ×1
bootloader ×1
devkitpro ×1
directive ×1
intel-syntax ×1
ld ×1
masm ×1
nasm ×1
thumb ×1