我将NASM源"移植"到GAS,我发现了以下几行代码:
push byte 0
push byte 37
Run Code Online (Sandbox Code Playgroud)
GAS不允许"推送字节"或"推送".
我应该如何将上述代码翻译成GAS语法?
谢谢
我正在使用 GAS 为 ARM Linux 构建程序,但我想做一些宏以使我的开发更加智能。那我想知道:
我怎么能为此做一个宏:(x+y*240)*2, wasx和yare int,它将像这样使用:
mov r0, MACRO_SHOULD_BE_CALLED_HERE
Run Code Online (Sandbox Code Playgroud)
我怎么能做一个应该像这样调用的宏:
JUST_MACRO_CALLED_HERE_TO_DO_SOMETHING
Run Code Online (Sandbox Code Playgroud)
这只会做一些已经在其中定义的事情,例如打印功能。
另外,如果我需要宏或函数调用的一些参数。我怎么能做到?
PS:r0是一个ARM寄存器,比如eaxx86
我正在尝试组装一小段 x86 代码。我在 32 位机器上,我编写了以下代码。它应该只是将值添加到 eax 中然后返回。我意识到不会有任何输出。当我编译这个使用
gcc main.S -o main
它编译没有错误。但是当我运行它时会出现段错误(gdb 声称它在第一条 movl 指令上出现段错误)。main.S 中有以下代码。我究竟做错了什么?
.text
.globl main
main:
pushl %ebp
movl %esp, %ebp
movl 0, %eax
addl $3, %eax
addl $3, %eax
leave
ret
Run Code Online (Sandbox Code Playgroud) 我有一个Linux x86-32 GAS汇编程序终止如下:
movl $1, %eax
movl $0, %ebx # argument for _exit
int $0x80
Run Code Online (Sandbox Code Playgroud)
当我像这样退出时,程序正常运行,但如果我尝试读取stdout输出,我什么也得不到(使用ie less或wc).
我尝试编译一个最小的C程序并比较strace输出.我发现的唯一区别是,GCC使得C程序(int main() { printf("donkey\n"); })隐含地退出exit_group(0)了strace输出.
我尝试修改我的ASM程序以退出call exit而不是原始系统调用.stdout现在可以正常读取.
测试用例
.data
douout: .string "monkey\n"
.text
.globl main
main:
pushl $douout
call printf
# Exit
movl $1, %eax
movl $0, %ebx
int $0x80
Run Code Online (Sandbox Code Playgroud)
编译并运行:
$ yasm -g dwarf2 -f elf -p gas t.asm && gcc -g -melf_i386 -o t t.o && ./t | wc -c
0
Run Code Online (Sandbox Code Playgroud)
预期:
7
Run Code Online (Sandbox Code Playgroud)
编辑:
我打过电话都 …
我正在尝试创建一个程序来在屏幕上编写参数.我创建了一些程序来获取C函数参数,或者我使用C将参数发送到我的asm程序.有没有办法只使用汇编程序获取程序参数
EX:
./Program "text"
Run Code Online (Sandbox Code Playgroud)
我正在使用(Gnu Assembler)
通常我会使用这些参数
[esp+4]
Run Code Online (Sandbox Code Playgroud)
因为esp是程序/函数调用指针,但在纯asm中它没有得到命令行参数.
有没有办法做到这一点?
我用Google搜索,但我无法找到更多信息
我被分配了一项理论上不太难的任务.应使用汇编程序代码(asm)更改AC变量.我已经完成了它并且它可以工作,但是赋值的第二部分是在不使用占位符(%)的情况下执行相同的操作.
我在这里不知所措,经过一些研究,我仍然没有找到解决方案.如何在不使用占位符来获取变量的情况下访问或操作汇编代码中的C变量?
这是带占位符的代码:
volatile uint8_t number = 1;
volatile uint8_t *number_pointer = &number;
asm volatile(
"ld r20, %a0" "\n\t"
"lsl r20" "\n\t"
"st %a0, r20" "\n\t"
"breq resetten" "\n\t"
"ret" "\n\t"
"resetten:" "\n\t"
"ldi r20, 1" "\n\t"
"st %a0, r20"
: "+e" (number_pointer)
);
Run Code Online (Sandbox Code Playgroud)
简而言之:如何在不使用%的情况下访问和更改"number_pointer"?(代码加倍"数字"直到它为128,然后它再次从1开始.)
两段示例代码;首先是一些调用程序集的 C++ 代码:
/* test1.cc */
#include <stdio.h>
extern "C" void blah();
extern "C" void stuff() {
printf( "This is a test\n" );
}
int main( int argc, char *argv[] ) {
blah();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
...然后大会:
.file "test2.s"
.text
.globl blah, stuff
.type blah,@function
.type stuff,@function
.align 16
blah:
/* normal function preamble */
pushl %ebp
movl %esp, %ebp
label1:
call stuff
leave
retn
Run Code Online (Sandbox Code Playgroud)
内置:
as -g --32 test2.s -o test2.o
clang++ -m32 -g test1.cc -c
clang++ -m32 -g …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,问题不会发生。
我该如何解决?
GNU汇编程序似乎有一些方法可以控制为某些指令发出的操作码的替代形式.例如
.intel_syntax noprefix
mov eax, ecx
mov.s eax, ecx
Run Code Online (Sandbox Code Playgroud)
处理上面的代码as test.s -o test.o && objdump -d test.o -M intel给出了以下反汇编:
0: 89 c8 mov eax,ecx
2: 8b c1 mov eax,ecx
Run Code Online (Sandbox Code Playgroud)
我们可以看到.s后缀似乎将89操作码切换到8b版本(并适当地更改了ModRM字节).
这种语法在GAS中如何工作?我找不到任何相关文件.
我有一个独立的 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 …