这是内核代码中header.S文件的代码片段.我无法理解lretw指令的作用.我已经查看了很多在线资源来获取该指令.
# We will have entered with %cs = %ds+0x20, normalize %cs so
# it is on par with the other segments.
pushw %ds
pushw $6f
lretw
Run Code Online (Sandbox Code Playgroud)
任何人都可以帮助我理解这个指令吗?
有谁知道 GAS 教程,我可以在其中找到有关在 64 位系统上在 AT&T 语法中编译和链接代码的信息?我在大学需要这个,所以我不能使用 nasm 代替。我能找到的所有 Tuts 要么适用于 nasm 或类似的东西,要么只能在 32 位上运行。即使我们的教授展示的简约示例也适用于我的 32 位系统,但不适用于 64 位系统。
如何生成可直接在 CPU 上运行的平面二进制文件?
也就是说,没有操作系统;也称为独立环境代码(请参阅在没有操作系统的情况下直接运行的程序的名称是什么?)。
我注意到我正在使用的as来自 OS-X 开发人员工具包的汇编器不断生成 Mach-O 文件,而不是平面二进制文件。
我想知道究竟.cfi_remember_state是如何实施的.我知道这是一个伪操作,所以我想它在组装时会转换成几条指令.我感兴趣的是用于实现它的确切指令.我尝试了很多方法来弄明白.即:
.cfi_remember_state条目只是一个简单的笑话(字面意思).在我看来,唯一的其他解决方案是读取已组装的可执行文件的二进制文件并尝试推断出指令.但我想避免这样一项艰巨的任务.有谁知道,启发我,它是如何在x86和/或x86-64上实现的?也许与分享获取信息的方式/位置一起,所以我可以检查其他伪操作,如果我有需要的话?
我想使用GCC扩展内联ASM编写以下循环:
long* arr = new long[ARR_LEN]();
long* act_ptr = arr;
long* end_ptr = arr + ARR_LEN;
while (act_ptr < end_ptr)
{
*act_ptr = SOME_VALUE;
act_ptr += STEP_SIZE;
}
delete[] arr;
Run Code Online (Sandbox Code Playgroud)
long具有长度的类型的数组ARR_LEN被分配并初始化为零。循环以的增量遍历数组STEP_SIZE。每个感动的元素都设置为SOME_VALUE。
好吧,这是我第一次在GAS中尝试:
long* arr = new long[ARR_LEN]();
asm volatile
(
"loop:"
"movl %[sval], (%[aptr]);"
"leal (%[aptr], %[incr], 4), %[aptr];"
"cmpl %[eptr], %[aptr];"
"jl loop;"
: // no output
: [aptr] "r" (arr),
[eptr] "r" (arr + ARR_LEN),
[incr] "r" (STEP_SIZE),
[sval] "i" (SOME_VALUE) …Run Code Online (Sandbox Code Playgroud) 当我在汇编中编程并使用标签时.byte,我在使用Qtspim. 我试图改变位置或值,但问题仍然存在,可能是标签。
错误回复在第 3 行。在标签的末尾,您可以找到解析器。
main:
.data
v : .byte 2,0,0,0,4,0,0,0
array: .byte 2,0,0,0,3,0,0,0,5,0,0,0,7,0,0,0,11,0,0,0,13,0,0,0,17,0,0,0,19,0,0,0
[..] # other code
Run Code Online (Sandbox Code Playgroud)
当我更改指令.byte时.space,问题不会发生。
我该如何解决?
我试图通过更改其中的一个字节来修改存储在内存中的字符串。我为此使用movb,但是由于某些原因,给定存储位置的字节未更改。
在gdb调试器上:
14 movb%al,(%r10)#next instr
(gdb)print / d $ al
$ 4 = 0
(gdb)print / c * $ r10
$ 5 = 47'/'
(gdb)s
16 mov $ 59,%rax
(gdb )打印/ c * $ r10
$ 6 = 47'/'
代码只是:
.globl _start
.text
_start:
call chamaexecve
variaveis:
.asciz "/bin/bashABBBBCCCC"
chamaexecve:
pop %r10
xor %rax, %rax
movb %al, (%r10) # problem happening here
mov $59, %rax
mov %rsi, %rdi
mov $0, %rsi
mov $0, %rdx
syscall
Run Code Online (Sandbox Code Playgroud)
它正在与as -gstabs -o shellf.o …
GAS对以下说明进行了以下编码:
push rbp # 0x55
push rbx # 0x53
push r12 # 0x41 0x54
push r13 # 0x41 0x55
Run Code Online (Sandbox Code Playgroud)
从AMD64规范(页313):
PUSH reg64 50 +rq将64位寄存器的上下文压入堆栈.
由于用于偏移rbp和rbx5个和3个,分别为第一两种编码有意义.但是我不明白最后两个编码是怎么回事.
据我所知,0x40-0x4f是一个REX前缀和0x41具有REX.B位集(其是一个扩展的MSB MODRM.rm或SIB.base,根据该外部参考).规范提到要访问所有16个GPR,你需要使用REX,但目前还不清楚截止点在哪里.
通过查阅MODRM和SIB的文档,我不认为使用了SIB,因为它的目的是使用base + offset寄存器进行索引(虽然说实话,我不能真正告诉你如何区分MODRM和SIB只是给出了编码).
所以,我怀疑这里使用的是MODRM.考虑到当前的push r12(0x41 0x54)(注意到r12有偏移12),我们有:
+----------------+--------------------+
| 0x41 | 0x54 |
+----------------+--------------------+
| REX | MODRM |
+--------+-------+-----+--------+-----+
| Prefix | WRXB | mod | reg …Run Code Online (Sandbox Code Playgroud) 我有一个独立的 Linux 独立 x86_64 hello world 工作岗位:
电源
.text
.global _start
_start:
asm_main_after_prologue:
/* Write */
mov $1, %rax /* syscall number */
mov $1, %rdi /* stdout */
lea msg(%rip), %rsi /* buffer */
mov $len, %rdx /* len */
syscall
/* Exit */
mov $60, %rax /* syscall number */
mov $0, %rdi /* exit status */
syscall
msg:
.ascii "hello\n"
len = . - msg
Run Code Online (Sandbox Code Playgroud)
我可以组装和运行:
as -o main.o main.S
ld -o main.out main.o
./main.out
Run Code Online (Sandbox Code Playgroud)
由于RIP …
我想知道如何在Intel语法的某些指令中将标签名称与寄存器名称区分开。例如,call rdx通常意味着间接跳转,但是如果我们rdx在同一程序集文件中有标签怎么办?我认为可以将其解释为直接跳转到rdx。是否有任何符号告诉汇编器是哪个?
gnu-assembler ×10
assembly ×6
x86-64 ×3
gcc ×2
linux ×2
x86 ×2
64-bit ×1
att ×1
c++ ×1
elf ×1
gdb ×1
intel ×1
intel-syntax ×1
ld ×1
linux-kernel ×1
machine-code ×1
macos ×1
symbols ×1