你不得不原谅我,我是x86装配和一般装配的新手.
所以我的问题是,我有类似的东西:
addl %edx,(%eax)
Run Code Online (Sandbox Code Playgroud)
%eax是一个寄存器,它包含一个指向某个整数的指针.我们称之为xp
这是否意味着它说:*xp = *xp + %edx?(%edx是整数)
我很困惑addl将存储结果的地方.如果%eax是指向int的指针,那么(%eax)应该是该int的实际值.因此,将addl存储的结果%edx+(%eax)中*xp?我真的很想有人向我解释这个!
我非常感谢任何帮助!
考虑 x64 Intel 程序集中的以下变量引用,其中变量a在.data节中声明:
mov eax, dword ptr [rip + _a]
Run Code Online (Sandbox Code Playgroud)
我很难理解这个变量引用是如何工作的。既然a是对应于变量运行时地址的符号(带重定位),如何[rip + _a]解引用正确的内存位置a?事实上,rip保存当前指令的地址,它是一个大的正整数,所以加法会导致错误的地址a?
相反,如果我使用 x86 语法(非常直观):
mov eax, dword ptr [_a]
Run Code Online (Sandbox Code Playgroud)
,我收到以下错误:64 位模式不支持 32 位绝对寻址。
有什么解释吗?
1 int a = 5;
2
3 int main() {
4 int b = a;
5 return b;
6 }
Run Code Online (Sandbox Code Playgroud)
编译gcc -S -masm=intel abs_ref.c -o abs_ref::
1 .section __TEXT,__text,regular,pure_instructions
2 .build_version macos, 10, 14
3 …Run Code Online (Sandbox Code Playgroud) 我目前正在玩x86 Assember,以提高我的低级编程技能.目前,我在32位保护模式下的寻址方案面临一些问题.
情况如下:
我有一个程序加载在0x7e0,它将CPU切换到保护模式并跳转到代码中的相应标签:
[...]
code to switch CPU in Protected Mode
[...]
jmp ProtectedMode
[...]
bits 32
ProtectedMode:
.halt:
hlt
jmp .halt
Run Code Online (Sandbox Code Playgroud)
到目前为止这个工作绝对正常."jmp ProtectedMode"在没有显式远跳的情况下工作以清除预取队列 - 因为该程序加载了偏移量0(开头的org 0) - 导致代码段指向正确的位置.
我现在的问题是,在"ProtectedMode"标签中我想跳转到另一个加载到0x8000的程序(我用内存转储检查了这个,加载函数确实正常工作,程序正确加载到0x8000) .
由于CPU现在处于ProtectedMode而不再是RealMode,因此寻址模式不同.ProtectedMode使用描述符选择器查找基址和描述符表中的限制,以添加给定的偏移量并检索物理地址(据我所知).因此,在进入ProtectedMode之前必须安装GDT.
我看起来如下:
%ifndef __GDT_INC_INCLUDED__
%define __GDT_INC_INCLUDED__
;*********************************
;* Global Descriptor Table (GDT) *
;*********************************
NULL_DESC:
dd 0 ; null descriptor
dd 0
CODE_DESC:
dw 0xFFFF ; limit low
dw 0 ; base low
db 0 ; base middle
db 10011010b ; access
db 11001111b ; granularity
db 0 …Run Code Online (Sandbox Code Playgroud) 由于这方面的网络资源稀少,为了将来的搜索,我将首先列出IA-32汇编语言(NASM)的地址模式,然后跟进一个简单的问题.
请注意,以上内容适用于NASM.对于MASM/TASM,您可以使用"mov esi,OFFSET foo"来获取地址,而"mov esi,foo"和"mov esi,[foo]"都将获得该值(对@Michael的信誉).
所以,在我的问题上.它与以下教程第29页底部的示例有关:http://www.tutorialspoint.com/assembly_programming/assembly_tutorial.pdf
它基本上将下面的代码列为间接内存寻址的示例.
MY_TABLE TIMES 10 DW 0 ; Allocates 10 words (2 bytes) each initialized to 0
MOV EBX, [MY_TABLE] ; Effective Address of MY_TABLE in EBX
MOV [EBX], 110 ; MY_TABLE[0] = 110
ADD EBX, 2 ; EBX = EBX +2
MOV [EBX], 123 ; MY_TABLE[1] …Run Code Online (Sandbox Code Playgroud) 我在边界寻址模式(cudaAddressModeBorder)中使用CUDA纹理.我正在阅读纹理坐标tex2D<float>().当纹理坐标落在纹理之外时,tex2D<float>()返回0.
如何将此返回的边框值更改0为其他值?我可以手动检查纹理坐标并自己设置边框值.我想知道是否有CUDA API我可以设置这样的边界值.
以下x86汇编程序指令有何功能?
call dword ptr ds:[00923030h]
Run Code Online (Sandbox Code Playgroud)
这是我怀疑的间接电话,但它究竟是如何计算通话的地址的呢?
我正在尝试将“main”的地址加载到 GNU 汇编器中的寄存器 (R10) 中。我没办法。在这里,我有什么和我收到的错误消息。
main:
lea main, %r10
Run Code Online (Sandbox Code Playgroud)
我还尝试了以下语法(这次使用 mov)
main:
movq $main, %r10
Run Code Online (Sandbox Code Playgroud)
使用以上两种方法,我都会收到以下错误:
/usr/bin/ld: /tmp/ccxZ8pWr.o: relocation R_X86_64_32S against symbol `main' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
使用 -fPIC 编译不能解决问题,只会给我同样的错误。
我不确定这add条指令在做什么:
add 0x0(%rbp,%rbx,4),%eax
Run Code Online (Sandbox Code Playgroud)
如果是:
add %rbx,%eax
Run Code Online (Sandbox Code Playgroud)
我知道它会添加内容rbx和内容eax并将它们存储回来eax.但是,这0x0(%rbp,%rbx,4)让我失望了.
以下陈述有什么区别?
mov %eax,%esp
mov %eax,(%esp)
Run Code Online (Sandbox Code Playgroud)
我正在努力扩散二进制炸弹,并且在装配早期遇到了一些mov和leal命令的问题.
英特尔和AT&T语法中内存寻址的一般形式如下:
[base + index*scale + disp]
disp(base, index, scale)
Run Code Online (Sandbox Code Playgroud)
我的问题如下:
base和index任意注册?scale采用什么值,是1,2,4和8(默认值为1)?index和disp可互换的(唯一的区别index是寄存器disp是一个常数)?