Assembly 如何将伪指令加载地址转换为实际指令?
我看过类似的问题,但它们没有解决下面的问题 在MIPS汇编中编程时,有一条伪指令称为加载地址(la) 我来自更高层次的语言,所以请容忍我,如果我还没有进入兔子洞 在查找此伪指令的翻译内容时,我在以下示例中发现:Assembly 如何将伪指令加载地址转换为实际指令?,assembly,mips,Assembly,Mips,我看过类似的问题,但它们没有解决下面的问题 在MIPS汇编中编程时,有一条伪指令称为加载地址(la) 我来自更高层次的语言,所以请容忍我,如果我还没有进入兔子洞 在查找此伪指令的翻译内容时,我在以下示例中发现: la $a0,address 转化为 lui $at, 4097 (0x1001 → upper 16 bits of $at). ori $a0,$at,disp 其中,immediate(“disp”)是第一个 数据位置(始终为0x 1001 0000)和第一个字节的地址 在字符
la $a0,address
转化为
lui $at, 4097 (0x1001 → upper 16 bits of $at).
ori $a0,$at,disp
其中,immediate(“disp”)是第一个
数据位置(始终为0x 1001 0000)和第一个字节的地址
在字符串中
我发现了另一个扩展:
# la $t, A
lui $t, A_hi
ori $t, $t, A_lo
基本上,我认为我理解后一种代码。我们希望使用一条指令在寄存器$t中放置一个32位地址,但对于I型指令,我们只能在指令中放置16位地址,因此我们需要两条指令,因为我们无法在一条指令中放置32位地址
第二个翻译与上面第一个翻译有什么关系?
另外,作为一个更实际的问题,假设我有以下装配程序:
.data
prompt1: .asciiz "How old are you?"
.text
main:
la $a0, prompt1
如何将la
指令替换为实际指令?
注:我可以看到模拟器将其转换为:
lui $1, 4097
ori $4, $1, 0
但在本例中,它使用寄存器$1,这是为汇编程序保留的寄存器。如果我自己写的说明正确的话,我就不能利用它了?此外,lui
将高位设置为1001。我知道静态数据从0x10010000开始,因此标记为prompt1
的字符串将从那里开始。但是(这一部分我可能还没有掌握程序员在汇编中应该如何控制),如果我在prompt1之后有另一个标签prompt2,我会准确地知道它在第一个标签之后有多少字节,以便正确地选择立即常数放入ori
编辑:为了将我正在做的事情上下文化,这里有一些代码(顺便说一下,这是我自己编写的第一个汇编程序):
听起来你有它,但可能是你忽略的缺失环节 首先,汇编语言是由汇编程序、程序而不是目标定义的。因此,可能会有很多不同的MIPS汇编语言,只要有人愿意编写汇编程序。幸运的是,没有,但有一些变化。它们变化的大部分地方不是助记符/指令。在MIPS包括伪指令la的情况下。但如注释所示,像%hi和%lo以及
.asciiz
这样的东西不一定跨越MIPS的所有汇编程序,只要la
是,也不需要跨越$a0、$v0寄存器名称也不是必需的
在这种情况下,伪指令意味着汇编程序将其替换为实指令。汇编程序的工作是生成真正的指令、机器指令/代码,或者尽可能做到最好。工具链理想情况下包括编译器、汇编器和链接器,因此C编译器将C代码转换为汇编程序,汇编器将其转换为对象,并获取一个或多个对象,并将其链接为二进制文件,该二进制文件理想情况下解析了所有外部(标签)
不同的指令集具有不同的功能/规则。有些人专门谈论寻址模式,有些人则没有。但是,当您编写C代码时,函数的名称(最初是变量的名称)会变成标签,标签就是地址。现在,优化器可能会删除这些内容的内存位置实例及其标签,结果地址会消失,但如果它们不这样做,它们就是一个地址。因此,当您调用函数时,需要在构建时由工具链计算出地址(存在重新定位异常,但在这些情况下,工具链仍然计算出相对于基址的地址,重新定位代码必须对基址进行修补,以便工具链输出正常工作)
有时地址是pc相关的,程序计数器是一个内部寄存器(或现在是一组寄存器),当程序员阅读一些清单时,它跟踪程序:
00000000 <.text>:
0: e3a01001 mov r1, #1
4: e3a02004 mov r2, #4
8: e0813002 add r3, r1, r2
可能是那个指示
其他指令集将尝试查找有时称为池的内容,并将常量放在附近。对于固定长度的指令集,您经常会看到这一点,但有时可能会根据指令集代码自行执行
ldr r0,=labelname
nop
b somewhere
是特定指令集的特定于汇编程序(而非目标)的伪代码。汇编器看到有一个无条件的分支,这意味着除非程序员正在做一些不正常的事情,否则不能执行该分支后面的字节。让我们声明这个标签labelname是外部的,在这个代码中找不到它,此时正在组装到这个对象中。因此,工具链将在以后填充它,汇编程序将获取所有这些信息,并在汇编时提供一个链接器可以在已知地址后填充的位置
00000000 <.text>:
0: e59f0004 ldr r0, [pc, #4] ; c <.text+0xc>
4: e1a00000 nop ; (mov r0, r0)
8: eafffffe b 0 <somewhere>
c: 00000000 andeq r0, r0, r0
如果我使用gnu交叉汇编程序(binutils的一部分)(对于主要操作系统来说比较容易获得):
给予
第节的分解。正文:
00000000 <.text>:
0: 3c021234 lui $2,0x1234
4: 34425678 ori $2,$2,0x5678
8: 3c021234 lui $2,0x1234
c: 24025678 li $2,22136
10: 3c021000 lui $2,0x1000
14: 34420008 ori $2,$2,0x8
构建它时,忽略链接器关于\u start的警告
mips-elf-as ex.s -o ex.o
mips-elf-as ex.s -o ex.o
mips-elf-ld -Ttext=0x1000 so.o ex.o -o so.elf
mips-elf-objdump -D so.elf
给予
(当然优化)给出
我要求在没有任何命令行参数的情况下这样做,我得到:
00000000 <.text>:
0: 3c021000 lui $2,0x1000
4: 03e00008 jr $31
8: 24420008 addiu $2,$2,8
及
是指工具知道位的位模式是什么,是否可以将其优化为一条指令,以及何时将位放入机器代码中,以使其完整并可执行
地址、浮点数、有符号整数、无符号整数、指针、ascii字符。这些对处理器来说都是简单的位模式,它们对程序员来说没有意义,但对处理器来说没有意义
mips-elf-as so.s -o so.o
mips-elf-objdump -D so.o
00000000 <.text>:
0: 3c021234 lui $2,0x1234
4: 34425678 ori $2,$2,0x5678
8: 3c021234 lui $2,0x1234
c: 24025678 li $2,22136
10: 3c021000 lui $2,0x1000
14: 34420008 ori $2,$2,0x8
la $2,some_ext_label
Disassembly of section .text:
00000000 <.text>:
0: 3c020000 lui $2,0x0
4: 24420000 addiu $2,$2,0
.globl some_ext_label
add $3,$4,$5
some_ext_label:
add $3,$4,$5
add $4,$5,$6
mips-elf-as ex.s -o ex.o
mips-elf-as ex.s -o ex.o
mips-elf-ld -Ttext=0x1000 so.o ex.o -o so.elf
mips-elf-objdump -D so.elf
Disassembly of section .text:
00001000 <_ftext>:
1000: 3c020000 lui $2,0x0
1004: 2442100c addiu $2,$2,4108
1008: 00851820 add $3,$4,$5
0000100c <some_ext_label>:
100c: 00851820 add $3,$4,$5
1010: 00a62020 add $4,$5,$6
mips-elf-as ex.s -o ex.o
mips-elf-as ex.s -o ex.o
mips-elf-ld -Ttext=0x87654444 so.o ex.o -o so.elf
mips-elf-objdump -D so.elf
87654444 <_ftext>:
87654444: 3c028765 lui $2,0x8765
87654448: 24424450 addiu $2,$2,17488
8765444c: 00851820 add $3,$4,$5
87654450 <some_ext_label>:
87654450: 00851820 add $3,$4,$5
87654454: 00a62020 add $4,$5,$6
la $3,hello
add $5,$6,$7
add $5,$6,$7
add $5,$6,$7
hello:
add $5,$6,$7
add $5,$6,$7
add $5,$6,$7
00000000 <hello-0x14>:
0: 3c030000 lui $3,0x0
4: 24630014 addiu $3,$3,20
8: 00c72820 add $5,$6,$7
c: 00c72820 add $5,$6,$7
10: 00c72820 add $5,$6,$7
00000014 <hello>:
14: 00c72820 add $5,$6,$7
18: 00c72820 add $5,$6,$7
1c: 00c72820 add $5,$6,$7
mips-elf-ld -Ttext=0x12345678 so.o -o so.elf
mips-elf-objdump -D so.elf
Disassembly of section .text:
12345678 <_ftext>:
12345678: 3c031234 lui $3,0x1234
1234567c: 2463568c addiu $3,$3,22156
12345680: 00c72820 add $5,$6,$7
12345684: 00c72820 add $5,$6,$7
12345688: 00c72820 add $5,$6,$7
1234568c <hello>:
1234568c: 00c72820 add $5,$6,$7
12345690: 00c72820 add $5,$6,$7
12345694: 00c72820 add $5,$6,$7
unsigned int fun ( void )
{
unsigned int a;
a = 0x12345678;
a = 0x12340000;
a = 0x00005678;
a = 0x10000008;
return(a);
}
Disassembly of section .text:
00000000 <fun>:
0: 3c021000 lui $2,0x1000
4: 03e00008 jr $31
8: 24420008 addiu $2,$2,8
Disassembly of section .text:
00000000 <fun>:
0: e3a00281 mov r0, #268435464 ; 0x10000008
4: e12fff1e bx lr
lui $2,0x1000
addiu $2,$2,8
jr $31
00000000 <.text>:
0: 3c021000 lui $2,0x1000
4: 03e00008 jr $31
8: 24420008 addiu $2,$2,8
la $2,0x10000008
jr $31
00000000 <.text>:
0: 3c021000 lui $2,0x1000
4: 03e00008 jr $31
8: 34420008 ori $2,$2,0x8
la $5,0x12345678
la $5,some_label