我正在尝试将以下内容从AT&T程序集转换为英特尔程序集:
pushl 2000
Run Code Online (Sandbox Code Playgroud)
现在这归结为:
ff 35 d0 07 00 00 pushl 0x7d0
Run Code Online (Sandbox Code Playgroud)
但无论我尝试什么,我都无法在英特尔synax中获得相同的效果,我尝试过:
intel asm
disassembly after compiling to at&t
push 2000
68 d0 07 00 00 push $0x7d0
push [2000]
68 d0 07 00 00 push $0x7d0
push dword ptr [2000]
68 d0 07 00 00 push $0x7d0
push dword ptr 2000
68 d0 07 00 00 push $0x7d0
Run Code Online (Sandbox Code Playgroud)
所以我没有线索,相当于"pushl 2000"?
我正在阅读英特尔处理器文档并同时编写一些基本的汇编代码.我在我的服务器上有两个nasm和as(GAS),我理解两个汇编程序的基本区别.
长期来说:
我也很感激您可以与我分享的任何偏好.
C++,ATT汇编
我有以下汇编代码:
push %ebp
mov %esp, %ebp
sub $0x28, %esp
(...)
Run Code Online (Sandbox Code Playgroud)
我的教科书声称通过从%esp中减去0x28(作为堆栈形成的一部分),12个字节被分配给变量.为什么从堆栈中减去十进制40分配12个字节?
我想学习C调用约定.为此,我编写了以下代码:
#include <stdio.h>
#include <stdlib.h>
struct tstStruct
{
void *sp;
int k;
};
void my_func(struct tstStruct*);
typedef struct tstStruct strc;
int main()
{
char a;
a = 'b';
strc* t1 = (strc*) malloc(sizeof(strc));
t1 -> sp = &a;
t1 -> k = 40;
my_func(t1);
return 0;
}
void my_func(strc* s1)
{
void* n = s1 -> sp + 121;
int d = s1 -> k + 323;
}
Run Code Online (Sandbox Code Playgroud)
然后我使用GCC使用以下命令:
gcc -S test3.c
Run Code Online (Sandbox Code Playgroud)
并想出了它的装配.我不会显示我得到的整个代码,而是粘贴函数my_func的代码.就是这个:
my_func:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16 …Run Code Online (Sandbox Code Playgroud) 我找到了汇编指令
cltd
Run Code Online (Sandbox Code Playgroud)
通过在英特尔架构上反汇编代码.我发现的描述是,它清除了%edx寄存器,但是我不明白发生了什么......有谁可以解释命令到底是做什么的?
Intel语法使用分号进行注释.当我切换到AT&T时,它实际上试图解释这些评论.
AT&T程序集的注释语法是什么?
我是装配工的新手.我正在阅读计算机系统程序员的观点.我不明白我如何选择后缀进行mov指导.我知道每个寄存器和位数.后缀使用由位计数(32位l,16位w,8位b)决定.很少有例子对前一句无效.例如,%esp是32位寄存器,但是使用4步骤后缀b代替l.请说明使用后缀.

问题:

回答: l-w-b-b-l-w-l
资料来源:计算机系统:程序员的观点(CSAPP),布莱恩特,奥哈拉伦
我刚刚开始学习ARM程序集,我不明白为什么GNU as语法与x86*不同.
由于指令是相同的,我会期望一切都像x86*,除了指令本身,但相反,我正在努力加载字符串的地址,等等.我从头开始通过在线阅读一些PDF ,man 2 syscall并反编译基本的例子,因为我不确定我可以在网上找到的各种Hello World的价值.
我的问题:
%印记#或一个$sigil.事实上,如果我编译mov r0, $0,objdump -D给我一个回复mov r0, #1.一切都汇集到了同样的东西mov r0, #1:
mov %r0, $1
10080: e3a00001 mov r0, #1
mov r0, $1
10084: e3a00001 mov r0, #1
mov %r0, #1
10088: e3a00001 mov r0, #1
mov r0, #1
1008c: e3a00001 mov r0, #1
Run Code Online (Sandbox Code Playgroud)
我无法直接使用标签的地址来加载字符串地址,所以我需要使用一个变量.mov r1, $hello或者ldr r1, $hello不工作.在x86_64中,我会写的mov $hello, %rsi.所以我正在做gcc所做的事情,我正在用另一个标签的地址创建一个单词.
我无法放置我的常量 …
最近,我读了一些关于计算机科学的书。我编写了一些 C 代码,并使用gcc和objdump反汇编了它们。
以下C代码:
#include <stdio.h>
#include <stdbool.h>
int dojob()
{
static short num[ ][4] = { {2, 9, -1, 5}, {3, 8, 2, -6}};
static short *pn[ ] = {num[0], num[1]};
static short s[2] = {0, 0};
int i, j;
for (i=0; i<2; i++) {
for (j=0; j<4; j++){
s[i] += *pn[i]++;
}
printf ("sum of line %d: %d\n", i+1, s[i]);
}
return 0;
}
int main ( )
{
dojob();
}
Run Code Online (Sandbox Code Playgroud)
得到以下汇编代码(AT&T 语法;只有函数dojob …
x86 汇编设计有指令后缀,如l(long), w(word), b(byte)。
所以我认为这jmpl是long jmp
但是当我编译它时它的工作很奇怪。
见下面的例子。
测试1:组装
main:
jmp main
Run Code Online (Sandbox Code Playgroud)
测试1:编译结果
eb fe jmp 0x0804839b <main>
Run Code Online (Sandbox Code Playgroud)
测试2:组装
main:
jmpl main # added l suffix
Run Code Online (Sandbox Code Playgroud)
测试2:编译结果
ff 25 9b 83 04 08 jmp *0x0804839b
Run Code Online (Sandbox Code Playgroud)
与Test1相比,Test2的结果出乎意料。
我认为它应该与Test1一样编译。
问:
是jmpl什么不同的指令在8086的设计?
(根据这里,jmpl在 SPARK 中意味着 jmp 链接。是这样的吗?)
...或者这只是 gnu 汇编程序上的错误?